2016-08-16 3 views
0

Я использую Entity Framework 6.0.0 в проекте, используя сначала код и API DbContext. В моем приложении есть 2 сущностей объектов, которые имеют один-ко-многим, как показано нижеСохранение одного EntityObject с Entity Framework code сначала

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?

+2

Показать код, как вы получаете/изменение сущности перед сохранением. – 3615

+0

Обновлен вопрос выше. – SohamC

+0

Вам нужно показать код, который вызывает 'Write' - как вы получаете сущности, которые передаются в качестве аргументов. Оба «Пишут» не имеют ничего плохого, проблема в том, что вы называете это последним. –

ответ

0

Когда вы получаете объект из DbContext, он считается прикрепленным к контексту, поэтому контекст знает о любых изменениях, которые вы делаете с сущностью. Поэтому после модификации объекта вы не должны добавлять его снова в DbContext или делать что-то особенное. Но если объект теряет соединение, то DbContext или новый, он должен быть добавлен в контекст.

Дополнительная информация о прикрепленных/отстраненных лицах может быть найдена here.

Я до сих пор не вижу полный код, но я думаю, что проблема возникает, потому что в какой-то момент какая-то сущность становится непривязанной, а затем модифицируется, и когда 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; } 
} 
Смежные вопросы