我在SQL(A)中有一个与另一个对象(B)有多对多关系的对象。我目前正在构建一个API层DLL,允许用户将类型B的对象分配到类型A.现在,用户将使用不同的LINQ数据上下文检索类型A的条目列表和类型B的条目列表。问题是与A关联的数据上下文将来自与B关联的数据上下文中的任何对象视为新的,并在我调用SubmitChanges()时尝试插入它们。有没有办法告诉数据上下文A这些对象已经存在并且不需要创建?我想写的代码看起来像这样(我称之为服务和B输出):
List<Service> svcs = Service.GetServices();
List<Output> outs = Output.GetOutputs();
svcs[0].OutputCollection.Add(outs);
svcs[0].Save();
我的示例中的每个Service对象都引用了从数据库中提取它的数据上下文,Save函数调用了DataContext.SubmitChanges();上面的代码抛出异常,因为它尝试将已存在的Output添加回表。
我知道这很长,我不确定我是否很好地解释了我的问题。任何见解或建议都会有所帮助。
答案 0 :(得分:2)
我实际上找到了一种不同的解决方案,现在我觉得有点愚蠢甚至提问。我在Service.Outputs.Add()方法中所做的实际上是问题所在:
public void Add(Output output)
{
OutputCollectionItem oci = new OutputCollectionItem();
oci.item = output;
this.OutputCollection.Add(oci);
}
我应该做的是:
public void Add(Output output)
{
OutputCollectionItem oci = new OutputCollectionItem();
oci.itemID = output.itemID;
this.OutputCollection.Add(oci);
}
答案 1 :(得分:0)
我遇到了同样的问题,我无法想出一个优雅的解决方案。但我找到的唯一解决方案是使用“拼接”或使用反射。
拼接看起来像这样。
Person existingPerson - DB.GetPerson(1);
existingPerson.BirthDate = newPerson.BirthDate;
existingPerson.JobTitle = newPerson.JobTitle;
我曾经读过一些关于使用回调的内容,但在我的生活中找不到它。
答案 2 :(得分:0)
我认为您必须从A和B中分离对象,而不是链接它们并在您的上下文中执行附加以重新附加它们。
这样:
// this remains
List<Service> svcs = Service.GetServices();
List<Output> outs = Output.GetOutputs();
svcs[0].OutputCollection.Add(outs);
svcs[0].Save();
// this changes
public class Service
{
public static List<Service> GetServices()
{
var context = new Context();
var result = context.ServiceSet.ToList();
result.ForEach(e => context.Detach(e));
return result;
}
public void Save()
{
var context = new Context();
context.Attach(this); // will retach myself and all of my child entities.
context.SaveChanges();
}
}
public class Output
{
public static List<Output> GetOutput()
{
var context = new Context();
var result = context.OutputSet.ToList();
result.ForEach(e => context.Detach(e));
return result;
}
}
答案 3 :(得分:0)
另一个解决方案是分享你的背景..
如果您使用IoC容器,您可以让容器管理您的上下文的生命周期,例如在网站中,最好根据请求结合上下文的生命周期。