2015-08-19 1 views
2

У меня есть два классаКак добавить связанный объект в контекст, в EF6

public class A 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public ICollection<B> { get; set; } 
} 

public class B 
{ 
    public int Id { get; set; } 
    public A A { get; set; } 
    public string Name { get; set; } 
} 

ICollection может быть пустым, так первым я создавать и добавлять объекты типа А следующим образом. Прежде всего, у меня есть универсальный метод для добавления элементов:

public void Add<T>(T item) 
{ 
    using (var context = new DbContext()) 
    { 
     context.Set<T>().Add(obj); 
     context.SaveChanges(); 
    } 
} 

, а затем:

A objA = new A() { Name = "Object A" }; 
Add<A>(objA); 

Пока все работает нормально. Моя проблема возникает при добавлении связанного объекта типа B.

B objB = new B() { Name = "Object B", A = objA } 
Add<B>(objB); 

Добавления objB результатов в дублировании objA (с различными Id). Я не уверен, где я ошибаюсь. Пожалуйста помоги.

Заранее спасибо.

ответ

1

Именно поэтому вряд ли когда-либо будет полезно иметь этот слой оберток вокруг DbContext и DbSet.

Единственного ваш метод Add может делать хорошо есть, добавить одногоA объекта в базу данных, и любой объект, подключенный к нему (также называется граф объектов). Метод DbSet.Add, который используется внутри него, маркирует каждый объект как Added, который является (1) доступным из экземпляра A и (2), который еще не прикреплен к контексту. Ну, вы создаете контекст внутри метода, поэтому нет возможности прикреплять вложенные объекты до добавления A.

Но это не единственная проблема. Вы также не можете добавить больше объектов (не более одного объекта A) в базу данных за одну транзакцию, если только вы не обернете все вызовы Add в TransactionScope. Нет способа использовать один вызов SaveChanges, чтобы совершить одну полную единицу работы.

Я не знаю, где находится этот метод Add, но вы должны каким-то образом реорганизовать свой код, чтобы иметь больше свободы манипулировать графом объектов перед сохранением изменений.

Без каких-либо обертках эта задача будет сделано так:

using(var context = new MyContext()) 
{ 
    A objA = context.As.Find(id); // id is a variable holding an existing A's Id 

    // Now objA is attached to the context and won't be added. 
    B objB = new B() { Name = "Object B", A = objA }; 
    context.Bs.Add(objB); 
    context.SaveChanges(); 
} 
0

Я предлагаю вам использовать ключевое свойство иностранного в классах:

public class A 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public ICollection<B> { get; set; } 
} 

public class B 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 

    [ForeignKey("A")] 
    public int AId { get; set; }  
    public virtual A A { get; set; } 
} 

Таким образом, вы можете установить эталонный идентификатор ключа вместо всего объекта при создании типа B.

B objB = new B() 
{ 
    Name = "Object B", 
    AId = objA.Id // Set object ID here 
}; 

Add<B>(objB); 

Надеюсь, это может вам помочь!

Смежные вопросы