2009-01-14 54 views
41

G'day everyone。使用linq生成直接更新,无需选择

我还在学习LINQ,所以原谅我,如果这是天真的。当您直接处理SQL时,可以使用条件生成更新命令,而无需运行select语句。

当我使用LINQ工作,我似乎遵循的模式:

  1. 选择实体
  2. 修改实体
  3. 提交更改

我想要做的就是直接更新使用linq和延期执行。实际执行是否可能直接在SQL中发生,而没有任何数据传输到客户端?

DataContext dc = new DataContext 

var q = from product in dc.Products 
     where product.Type = 1 
     set product.Count = 0 

dc.SubmitChanges 

因此,在本质LINQ有它需要的所有不使用选择生成的更新命令的信息。它会运行SQL:

Update Products Set Count = 0 Where Type = 1 

在LINQ中是否存在像“set”这样的关键字?

+0

目前接受的答案是错误的 - 您能选择正确的答案吗? – laktak 2015-10-07 07:49:44

+0

下面的答案不允许我所描述的基于集合的更新,但它们很有趣。 – Spence 2015-10-08 00:03:06

回答

29

没有,既不LINQ也没有的LINQ to SQL已经基于集的更新功能。

在LINQ to SQL中,您必须查询您希望更新的对象,根据需要更新字段/属性,然后调用SubmitChanges()。例如:

var qry = from product in dc.Products where Product.Name=='Foobar' select product; 
var item = qry.Single(); 
item.Count = 0; 
dc.SubmitChanges(); 

如果你希望做配料:

var qry = from product in dc.Products where Product.Type==1 select product; 
foreach(var item in qry) 
{ 
    item.Count = 0; 
} 
dc.SubmitChanges(); 

或者,您可以编写查询自己:

dc.ExecuteCommand("update Product set Count=0 where Type=1", null); 
+1

这是我的代码,我想知道LINQ是否有它的语法。欢呼的答案,但确实有更新发生在C#中,因为我猜如果你想编写SQL,你应该只写sql执行命令功能。 – Spence 2009-01-14 23:42:54

+0

我同意;我更喜欢使用代码内方法。 – Randolpho 2009-01-21 17:00:35

+9

这真的很笨,linq到sql应该有更新字段 – jdelator 2009-07-09 06:20:19

3

Linq 2 SQL没有SQL的直接插入/更新/删除等价物。在V1中,您可以使用linq进行的唯一更新是上下文中的SubmmitChanges或者如果您退回到sql。

但是有些人试图用自定义实现来克服linq的这个限制。

Linq batch update.

+0

干杯队友,这是一个非常有趣的阅读。让我们希望其中一些进入C#4或5,因为批量更新和删除的能力是LINQ实际缺少的唯一东西。 – Spence 2009-01-14 23:40:10

3

的PLINQO(http://plinqo.com)框架使用LINQ批量更新以执行更新

context.Task.Update(t => t.Id == 1, t2 => new Task {StatusId = 2});

这将执行Update Task Set StatusId = 2 Where Id = 1

43

实际上,你可以让LINQ到SQL生成更新语句:

Foo foo=new Foo { FooId=fooId }; // create obj and set keys 
context.Foos.Attach(foo); 
foo.Name="test"; 
context.SubmitChanges(); 

在你的dbml设置UpdateCheck的= “从不” 的所有属性。

这将生成单个更新语句,而不必首先进行选择。

一个忠告:如果你希望能够设置名称为空,你将有你的Foo对象初始化为不同的值,这样的LINQ可以检测到的变化:如果你想检查

Foo foo=new Foo { FooId=fooId, Name="###" }; 
... 
foo.Name=null; 

时间戳同时更新,你可以做到这一点还有:

Foo foo=new Foo { FooId=fooId, Modified=... }; 
// Modified needs to be set to UpdateCheck="Always" in the dbml 
-2

试试这个:

dbEntities.tblSearchItems 
    .Where(t => t.SearchItemId == SearchItemId) 
    .ToList() 
    .ForEach(t => t.isNew = false); 
dbEntities.SaveChanges(); 
0

我们E本扩展方法:EntityExtensionMethods.cs

public static void UpdateOnSubmit<TEntity>(this Table<TEntity> table, TEntity entity, TEntity original = null) 
    where TEntity : class, new() 
{ 
    if (original == null) 
    { 
     // Create original object with only primary keys set 
     original = new TEntity(); 
     var entityType = typeof(TEntity); 
     var dataMembers = table.Context.Mapping.GetMetaType(entityType).DataMembers; 
     foreach (var member in dataMembers.Where(m => m.IsPrimaryKey)) 
     { 
      var propValue = entityType.GetProperty(member.Name).GetValue(entity, null); 
      entityType.InvokeMember(member.Name, BindingFlags.SetProperty, Type.DefaultBinder, 
       original, new[] { propValue }); 
     } 
    } 

    // This will update all columns that are not set in 'original' object. For 
    // this to work, entity has to have UpdateCheck=Never for all properties except 
    // for primary keys. This will update the record without querying it first. 
    table.Attach(entity, original); 
} 

要使用它,请确保您传递给UpdateOnSubmit方法entity对象拥有所有你想要更新的记录集的主键属性。然后该方法将使用entity对象的其余属性更新记录,而不先拔出记录。

致电UpdateOnSubmit后,请务必致电SubmitChanges()以应用更改。