C# 使用实体框架保存推文

C# 使用实体框架保存推文,c#,entity-framework,twitter,entity-framework-6,twitter-streaming-api,C#,Entity Framework,Twitter,Entity Framework 6,Twitter Streaming Api,我试图用Entity Framework保存状态消息,但问题是每次我试图保存数据库中已经存在的用户的tweet时,都会出现异常 {"A duplicate value cannot be inserted into a unique index. [ Table name = users,Constraint name = PK_dbo.users ]"} 我完全理解我为什么会犯这个错误,但不知道如何防止它 要保存状态消息,请执行以下操作 第1版: 每个状态消息都包含作为子实体的完整用户信息。

我试图用Entity Framework保存状态消息,但问题是每次我试图保存数据库中已经存在的用户的tweet时,都会出现异常

{"A duplicate value cannot be inserted into a unique index. [ Table name = users,Constraint name = PK_dbo.users ]"}
我完全理解我为什么会犯这个错误,但不知道如何防止它

要保存状态消息,请执行以下操作

第1版:

每个状态消息都包含作为子实体的完整用户信息。我使用这段代码的Modelstatus.cs和user.cs:

根据此问题提供的信息: 我想到了这个主意:

第2版:

TweetContext.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;

namespace TwitterStreamClient
{
    class TweetContext : DbContext
    {
        public DbSet<status> status { get; set; }
        public DbSet<user> user { get; set; }

        static TweetContext()
        {
            // Database initialize
            Database.SetInitializer<TweetContext>(new DbInitializer());
            using (TweetContext db = new TweetContext())
                db.Database.Initialize(false);
        }

        class DbInitializer : DropCreateDatabaseAlways<TweetContext>
        {
        }
    }
}

我在执行insert时遇到了同样的问题,但在遇到错误时,我重新初始化了dbcontext 我的问题解决了我不明白但对我来说很好

just reinitialize your dbcontext  and check ....
我找到了解决办法

在上面的版本2中,我只需要将SingleOrDefault更改为Any


我猜使用SingleOrDefault获取用户的问题是跟踪具有此ID的用户,因此附件会引发异常,因为它已经跟踪具有此ID的用户。但是当我使用任何ID时,它只检查具有此密钥的用户是否存在,而不跟踪它!因此,连接用户是可能的。

请分享您的状态表和用户表设置,以及您正在使用的当前代码,更准确地说,在此db.status.Addstatus之前您在做什么;db.SaveChanges;我已经添加了您要求的代码片段!我认为主要的问题是,我必须告诉EF,如果用户已经存在,就需要更新。但当我尝试使用“附加”时,它告诉我。。。相同类型的另一个实体已具有相同的主键值。但就我所见,我完全遵循这里描述的方案:将一个现有但已修改的实体附加到contextHi Miike,到目前为止看起来很不错,我可以要求您添加您的TweetContext设置,尤其是用户和状态实体。我对它们的配置更感兴趣,所以我可以看到主键等等。但也看看我找到的解决方案。。。有更好的方法吗?太好了,你的解决方案对我来说很好,我看不出你所做的有什么错。我有一个问题,这个项目有多大,你打算在多少地方使用这些代码?如果它的大小合适,您可能需要考虑使用小型存储库模式,这样您就可以简单地调用repo上的helper方法,可能称为InsertOrUpdateargs。我只是不知道为什么您的查询需要。您应该能够简单地编写db.user.Whereu=>u.Id==status.user.Id.Any
using System;
using System.Globalization;
using System.Runtime.Serialization;
using System.ComponentModel.DataAnnotations;

namespace TwitterStreamClient
{
    [DataContract]
    public class user
    {
        //<user>
        //<id>1401881</id>
        // <name>Doug Williams</name>
        // <screen_name>dougw</screen_name>
        // <location>San Francisco, CA</location>
        // <description>Twitter API Support. Internet, greed, users, dougw and opportunities are my passions.</description>
        // <profile_image_url>http://s3.amazonaws.com/twitter_production/profile_images/59648642/avatar_normal.png</profile_image_url>
        // <url>http://www.igudo.com</url>
        // <lang>en</lang>
        // <protected>false</protected>
        // <followers_count>1027</followers_count>
        // <profile_background_color>9ae4e8</profile_background_color>
        // <profile_text_color>000000</profile_text_color>
        // <profile_link_color>0000ff</profile_link_color>
        // <profile_sidebar_fill_color>e0ff92</profile_sidebar_fill_color>
        // <profile_sidebar_border_color>87bc44</profile_sidebar_border_color>
        // <friends_count>293</friends_count>
        // <created_at>Sun Mar 18 06:42:26 +0000 2007</created_at>
        // <favourites_count>0</favourites_count>
        // <utc_offset>-18000</utc_offset>
        // <time_zone>Eastern Time (US & Canada)</time_zone>
        // <profile_background_image_url>http://s3.amazonaws.com/twitter_production/profile_background_images/2752608/twitter_bg_grass.jpg</profile_background_image_url>
        // <profile_background_tile>false</profile_background_tile>
        // <statuses_count>3390</statuses_count>
        // <notifications>false</notifications>
        // <following>false</following>
        // <verified>true</verified>
        // <contributors_enabled>false</verified>
        //</user> 

        [DataMember]
        [Key]
        public string id { get; set; }
        [DataMember]
        public string name { get; set; }
        [DataMember]
        public string screen_name { get; set; }
        [DataMember]
        public string location { get; set; }
        [DataMember]
        public string description { get; set; }
        [DataMember]
        public string profile_image_url { get; set; }
        [DataMember]
        public string url { get; set; }
        [DataMember]
        public string lang { get; set; }
        [DataMember]
        public string @protected { get; set; }
        [DataMember]
        public string followers_count { get; set; }
        [DataMember]
        public string profile_background_color { get; set; }
        [DataMember]
        public string profile_text_color { get; set; }
        [DataMember]
        public string profile_link_color { get; set; }
        [DataMember]
        public string profile_sidebar_fill_color { get; set; }
        [DataMember]
        public string profile_sidebar_border_color { get; set; }
        [DataMember]
        public string friends_count { get; set; }
        //save date only as string for now as DateTimeOffset is not supported
        //public DateTimeOffset created_at_dt { get; set; }
        [DataMember]
        public string created_at
        {
            get ; //{ return created_at_dt.ToString("ddd MMM dd HH:mm:ss zzz yyyy"); }
            set;  //{ created_at_dt = DateTimeOffset.ParseExact(value, "ddd MMM dd HH:mm:ss zzz yyyy", CultureInfo.InvariantCulture);           }
        }
        [DataMember]
        public string favourites_count { get; set; }
        [DataMember]
        public string utc_offset { get; set; }
        [DataMember]
        public string time_zone { get; set; }
        [DataMember]
        public string profile_background_image_url { get; set; }
        [DataMember]
        public string profile_background_tile { get; set; }
        [DataMember]
        public string statuses_count { get; set; }
        [DataMember]
        public string notifications { get; set; }
        [DataMember]
        public string following { get; set; }
        [DataMember]
        public string verified { get; set; }
        [DataMember]
        public string contributors_enabled { get; set; }
    }
}
using System;
using System.Runtime.Serialization;
using System.Globalization;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace TwitterStreamClient
{
    //<status>
    //<created_at>Tue Apr 07 22:52:51 +0000 2009</created_at>
    //<id>1472669360</id>
    //<text>At least I can get your humor through tweets. RT @abdur: I don't mean this in a bad way, but genetically speaking your a cul-de-sac.</text>
    //<source><a href="http://www.tweetdeck.com/">TweetDeck</a></source>
    //<truncated>false</truncated>
    //<in_reply_to_status_id></in_reply_to_status_id>
    //<in_reply_to_user_id></in_reply_to_user_id>
    //<favorited>false</favorited>
    //<in_reply_to_screen_name></in_reply_to_screen_name>
    //<geo/>
    //<contributors/>
    //</status>

    [DataContract]
    public class status
    {
        [DataMember]
        [Key]
        public string id { get; set; }
        //save date only as string for now as DateTimeOffset is not supported
        //public DateTimeOffset created_at_dt { get; set; }
        [DataMember]
        public string created_at
        {
            get; //{ return created_at_dt.ToString("ddd MMM dd HH:mm:ss zzz yyyy"); }
            set; //{ created_at_dt = DateTimeOffset.ParseExact(value, "ddd MMM dd HH:mm:ss zzz yyyy", CultureInfo.InvariantCulture);            }
        }


        [DataMember]
        public string text { get; set; }
        [DataMember]
        public string source { get; set; }
        [DataMember]
        public string truncated { get; set; }
        [DataMember]
        public string in_reply_to_status_id { get; set; }
        [DataMember]
        public string in_reply_to_user_id { get; set; }
        [DataMember]
        public string favorited { get; set; }
        [DataMember]
        public string in_reply_to_screen_name { get; set; }
        [DataMember]
        public user user { get; set; }
        [DataMember]
        public geo geo { get; set; }
        [DataMember]
        public string contributors { get; set; }
    }

    [DataContract]
    public class geo
    {
        [Key]
        public int geoId { get; set; }
        [DataMember]
        public string type { get; set; }
        [DataMember]
        public string[] coordinates { get; set; }
    }
}
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;

namespace TwitterStreamClient
{
    class DataStore
    {
        static private TweetContext Db = null;

        private static TweetContext  getContext() {
            if(Db == null)
            {
                Db = new TweetContext();
            }
            return Db;
        }
        public static bool Add(status status)
        {
            TweetContext db = getContext();
            {
                db.status.Add(status);
                db.SaveChanges();
                return true;
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;

namespace TwitterStreamClient
{
    class TweetContext : DbContext
    {
        public DbSet<status> status { get; set; }
        public DbSet<user> user { get; set; }

        static TweetContext()
        {
            // Database initialize
            Database.SetInitializer<TweetContext>(new DbInitializer());
            using (TweetContext db = new TweetContext())
                db.Database.Initialize(false);
        }

        class DbInitializer : DropCreateDatabaseAlways<TweetContext>
        {
        }
    }
}
just reinitialize your dbcontext  and check ....
if(!db.user.Where<user>(u => u.id == status.user.id).Any<user>())
    db.user.Add(status.user);
else
{
    //db.user.Attach(status.user);
    db.Entry(status.user).State = EntityState.Modified;
}
    db.status.Add(status);
    db.SaveChanges();