【问题标题】:Best way to update in Linq To SQL在 Linq To SQL 中更新的最佳方法
【发布时间】:2010-10-14 15:43:09
【问题描述】:

我有几个实体类用于解析固定宽度的文本文件以及利用 Linq to SQL。我使用这些类来解析所述文本文件中的数据,并与数据库中的数据进行比较。

其中一个实体有很多属性,我不想浪费时间在 Linq 结果对象上设置每个单独的属性。

有没有办法告诉 Linq“这是我的对象,用它来更新记录”?这是我正在处理的代码:

if (partialContent.MonthlyAddChange == "A") { bookContentTable.InsertOnSubmit(partialContent); } 否则 if (partialContent.MonthlyAddChange == "C") { var query = 来自 bookContentTable 中的 bookContent 其中 bookContent.EAN == partialContent.EAN 选择书籍内容; 如果(查询!= null) { // 用 query.First() 做一些事情 } } }

在这种情况下删除记录并执行 InsertOnSubmit() 会更好吗?

【问题讨论】:

  • “查询”变量永远不会为空,序列可以为空,但不能为空。

标签: .net visual-studio-2008 linq linq-to-sql


【解决方案1】:

在这种情况下删除记录并执行 InsertOnSubmit() 会更好吗?

不,绝对不是——只要考虑任何好的、稳定的数据库设计都应该使用的引用完整性。如果您的记录已被其他行使用,则不能简单地将其删除并重新插入 - 您会破坏这些完整性约束。

如果您只是更改一些值,请更新现有行 - 更容易且更一致。

马克

【讨论】:

    【解决方案2】:

    我认为您可以使用 DataContext.Table.Attach(record, true) 和 DataContext.SubmitChanges() 之类的东西。但我并没有完全充实...

    所以现在我做了一个测试。这仅在您不需要并发检查时才有效(即您是唯一更新表的人)。

    这是我的桌子

    People
    PersonID int
    FirstName varchar(50)
    LastName varchar(50)
    

    我用以下记录填充了表格

    > PersonID     FirstName    LastName
    > 1            Jason        Punyon
    

    我只使用名为 PeopleDataContext 的表创建了一个 LINQ2SQL DataContext,并且在 People 类的每个属性上,我将每个记录属性的 UpdateCheck 属性设置为 Never。

    代码如下:

    static void Main(string[] args)
    {
        var p = new People();
        p.PersonID = 1;
        p.FirstName = "Jason";
        p.LastName = "This is a new last name";
    
    
        using (var db = new PeopleDataContext())
        {
            db.Peoples.Attach(p, true);
            db.SubmitChanges();
        }
    }
    

    它成功地工作了。没有反射或任何东西,但就像我说的,你失去了并发检查。

    【讨论】:

    • 你能不能用大写字母来改变更新检查属性,因为如果你不需要担心并发性,这基本上就是答案
    【解决方案3】:

    您可以考虑使用自动映射器为您复制值。查看更多信息:http://www.lostechies.com/blogs/jimmy_bogard/archive/2009/01/22/automapper-the-object-object-mapper.aspx

    【讨论】:

      【解决方案4】:

      我认为编辑记录的概念与删除和插入新记录的概念不同。基本上,我认为 ORM 应该抽象出主键生成和其他相关内容。通过删除和插入,您可能会删除记录的完整性(可能会发布新的主键,使引用的实体无效等等......)。我建议每当您采取的操作在概念上是更新时更新记录。

      【讨论】:

        【解决方案5】:

        我不会删除/重新创建。假设这两个对象对于要更新的​​属性具有相同的接口,我将使用反射并将更改的值复制到现有对象。如果任何值与原始值不同,记录将被标记为需要更新,并且 SubmitChanges 会处理它。

        例如(几乎没有错误检查):

         foreach (var bookInfo in bookContent.GetType().GetProperties())
         {
             var partialInfo = partialContent.GetType().GetProperty( bookInfo.Name );
             if (partialInfo != null)
             {
                 bookInfo.SetValue( partialInfo.GetValue( partialContent, null ) );
             }
         }
        

        如果您知道它们是同一类型,则可以重用第一个 PropertyInfo 而不是为 partialContent 获取新的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-02-21
          • 1970-01-01
          • 2010-10-10
          • 2011-03-02
          • 2010-10-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多