簡體   English   中英

首先使用實體​​框架代碼保存單個EntityObject

[英]Saving single EntityObject with Entity Framework code first

我在一個項目中使用Entity Framework 6.0.0,首先使用代碼和DbContext API。 在我的應用中,有2個具有一對多關系的實體對象,如下所示

class RefTable {
  [Key]
  public int Id { get; set; }
  public string RefName { get; set; }
  public virtual ICollection<Data> DataDetails { get; set; }
}

public class Data
{
    [Key]
    public int Id { get; set; }
    public string RefId { get; set; }
    [ForeignKey("RefId")]
    public virtual RefTable Machine { get; set; }
}

RefTable將在應用程序啟動時填充,並且幾乎不會進行任何更改。 但是, Data將不時發生變化。

我的Context.cs如下

 public class MyDbContext : DbContext
 {
     public MyDbContext()
         : base("name=CounterDbString")
     {
         Database.SetInitializer<MyDbContext>(new CreateDatabaseIfNotExists<MyDbContext>());
     }

     public DbSet<RefTable> RefData { get; set; }

     public DbSet<Data> Data { get; set; }
 }

我用來保存數據的代碼

 public void Write(IList<RefTable> refDataList)
 {
  foreach (var entity in refDataList)
  {
      var element = myContext.RefData.Find(entity.Id);
      if (element == null)
      {
          myContext.RefData.Add(entity);
      }
  }
    myContext.SaveChanges();
 }

 public void Write(IList<Data> dataList)
 {
    myContext.Data.AddRange(dataList);
    myContext.SaveChanges();
 }

當我嘗試在第二個函數中執行myContext.SaveChanges()時,總是會收到更新錯誤,指出violation of Primary Key因為它試圖將相同的數據插入RefTable 有沒有一種方法可以只保存Data對象中的更改?

當您從DbContext獲取實體時,它被認為是附加到上下文的,因此上下文知道您對實體所做的任何更改。 因此,在修改實體后,您不應將其再次添加到DbContext或對其進行特殊處理。 但是,如果實體丟失了它與DbContext的連接或是一個新的連接,則應將其添加到上下文中。

這里可以找到更多有關附着/分離的實體的信息

我仍然看不到完整的代碼,但是我認為問題會發生,因為在某些時候某個實體變得未連接,然后被修改,並且當SaveChanges發生時被認為是新實體,從而導致FK錯誤。

這是一個基本工作原理的小例子:

  private static void Main(string[] args) {
        var db = new MyDbContext();

        var reftable1 = new RefTable() {Id = 100, RefName = "ref1"};
        var listData1 = new List<Data>();
        for (int i=0; i<5; i++)
            listData1.Add(new Data() {Id = i, Machine =  reftable1, RefId = reftable1.Id});
        reftable1.DataDetails = listData1;
        db.RefData.Add(reftable1);

        var reftable2 = new RefTable() {Id = 200, RefName = "ref2"};
        var listData2 = new List<Data>();
        for (int i=5; i<10; i++)
            listData2.Add(new Data() {Id = i, Machine =  reftable2, RefId = reftable2.Id});
        reftable2.DataDetails = listData2;

        db.RefData.Add(reftable2);
        db.SaveChanges();

        db = new MyDbContext(); //lose connection to existing dbContext
        //now reftable1 is unattached, so if not lookup it from new dbContext it will be recreated!!!
        reftable1 = db.RefData.Single(x => x.RefName == "ref1"); //comment to see the difference

        //perform some update
        var data = db.Data.Where(x => x.Id > 7).ToList();
        foreach (var d in data) {
            d.Machine = reftable1;
        }
        db.SaveChanges();

        Console.ReadLine();
    }

而您的班級做了些微改動:

public class RefTable {
    [Key]
    public int Id { get; set; }

    public string RefName { get; set; }

    public virtual ICollection<Data> DataDetails { get; set; }
}

public class Data {
    [Key]
    public int Id { get; set; }

    public int RefId { get; set; }

    [ForeignKey("RefId")]
    public virtual RefTable Machine { get; set; }
}

public class MyDbContext : DbContext {
    public MyDbContext()
        : base("name=CounterDbString") {
        Database.SetInitializer(new CreateDatabaseIfNotExists<MyDbContext>());
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Entity<RefTable>().HasMany(x => x.DataDetails).WithRequired(x => x.Machine);
        base.OnModelCreating(modelBuilder);
    }

    public DbSet<RefTable> RefData { get; set; }

    public DbSet<Data> Data { get; set; }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM