使用linq生成直接更新而不select

每个人,每天。

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

当我使用LINQ时,我似乎遵循以下模式:

  1. select实体
  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拥有它所需要的所有信息,而不需要使用select来生成更新命令。 它会运行SQL:

 Update Products Set Count = 0 Where Type = 1 

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

不,LINQ和LINQ to SQL都没有基于集合的更新function。

在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); 

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

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

在你的Dbml中为所有属性设置UpdateCheck =“Never”。

这将生成一个单独的更新语句,而不必先做一个select。

一个警告:如果你想能够将Name设置为null,你将不得不将你的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 

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

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

Linq批量更新。

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

使用这种扩展方法: 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对象具有为要更新的logging设置的所有主键属性。 然后该方法将使用来自entity对象的其余属性更新logging,而不先拉动logging。

在调用UpdateOnSubmit ,请确保调用SubmitChanges()以应用更改。

尝试这个 :

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