【问题标题】:Changing a LINQ objects data context更改 LINQ 对象数据上下文
【发布时间】:2008-11-19 20:02:19
【问题描述】:

我在 SQL (A) 中有一个对象,它与另一个对象 (B) 具有多对多关系。我目前正在构建一个 API 层 DLL,它允许用户将 B 类型的对象分配给 A 类型。现在用户将使用不同的 LINQ 数据上下文检索 A 类型的条目列表和 B 类型的条目列表.问题是与 A 关联的数据上下文将与 B 关联的数据上下文中的任何对象视为新对象,并在我调用 SubmitChanges() 时尝试插入它们。有没有办法告诉数据上下文 A 这些对象已经存在并且不需要创建?我想写的代码看起来像这样(我将调用 A 服务和 B 输出):

List<Service> svcs = Service.GetServices();
List<Output> outs = Output.GetOutputs();

svcs[0].OutputCollection.Add(outs);
svcs[0].Save();

我的示例中的每个 Service 对象都有一个对从数据库中提取它的数据上下文的引用,并且 Save 函数调用 DataContext.SubmitChanges();上面的代码抛出异常,因为它试图将已经存在的输出添加回表中。

我知道这很长,但我不确定我是否很好地解释了我的问题。任何见解或建议都会有所帮助。

【问题讨论】:

    标签: c# sql linq


    【解决方案1】:

    我实际上找到了一种不同的解决方案,现在我什至觉得问这个问题有点愚蠢。我在 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);
    }
    

    【讨论】:

      【解决方案2】:

      我认为您必须将对象从 A 和 B 中分离出来,而不是链接它们并在您的上下文中执行 Attach 以重新附加它们。

      所以:

      // 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】:

      另一种解决方案是分享您的上下文..

      如果您使用 IoC 容器,您可以让容器管理上下文的生命周期,例如在网站中,将每个请求的上下文生命周期结合起来是个好主意。

      【讨论】:

        【解决方案4】:

        我遇到了同样的问题,我想不出一个优雅的解决方案。但我找到的唯一解决方案是使用“拼接”或使用反射。

        拼接看起来像这样。

        Person existingPerson - DB.GetPerson(1);
        existingPerson.BirthDate = newPerson.BirthDate;
        existingPerson.JobTitle = newPerson.JobTitle;
        

        我曾经读过一些关于使用回调的文章,但我一辈子都找不到它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-12-03
          • 2011-01-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多