我有两个班级
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可能为null所以首先我按以下方式创建和添加类型A的对象。首先,我有一个添加项目的通用方法:
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)。我不确定我错在哪里。请帮忙。
提前致谢。
答案 0 :(得分: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();
}
答案 1 :(得分: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类型时设置引用键ID而不是整个对象。
B objB = new B()
{
Name = "Object B",
AId = objA.Id // Set object ID here
};
Add<B>(objB);
希望它可以帮到你!