我有一个表格,其中图像为varbinary(max(,另一个数据(具有另一种类型(,它们更紧凑。我想更新另一个数据,但不是图像。在循环(即所有记录(中,过滤器选择要更新的记录。我找到了各种解决方案,但它们都使用将整个记录提取到上下文中或将现有记录(即之前某个时间获取或创建(附加到上下文中。说"在之前的某个时间获取或创建",我的意思是显示包含所有字段的整个记录 - 而不是从图像或其他"不必要的"字段上切下来。
有没有办法在不获取任何不必要的数据(例如 varbinary 图像(的情况下更新记录,而是通过 EF?也许只是获取任何轻量级 POCO 对象,而没有所有字段,但只有我需要的字段?或者此类任务位于 EF 的分配之外,我必须使用纯 SQL?
好吧,只是一个简单的例子:
数据库表:
create table Weed
(
Id int identity(1,1) not null,
Name nvarchar(100) not null,
Description nvarchar(max) null,
Image varbinary(max) null
)
英孚的 POCO
public partial class Weed
{
public Weed()
{}
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public byte[] Image { get; set; }
}
我想在不获取整个杂草(尤其是图像字段(的情况下更新描述,例如,对于名称以"A"开头的杂草。
在实体框架中,如果要在不首先获取实体的情况下进行更新,则应能够使用DbContext.Entry
方法,如下所示:
var model = new MyModel() { Id = id, OtherData = data };
using (var db = new MyEfContextName())
{
db.MyModels.Attach(model);
db.Entry(model).Property(x => x.OtherData).IsModified = true;
db.SaveChanges();
}
这应该告诉 EF 为你生成相应的 UPDATE 语句,而无需选择实体数据。
另一方面,如果需要先执行简短的 SELECT 以检索 Id,例如,当您使用 Linq to Entities 进行选择时,可以使用匿名类型:
var existingData = db.MyModels.Where(x => x.SomeParameter == someValue).Select(x => new { Id = x.Id, OtherData = x.OtherData }).SingleOrDefault();
这将生成一个 SELECT 语句,该语句仅选择您需要的数据并将其输出为匿名类型。
我应该注意,如果您正在执行复杂的查询或正在寻找效率,那么不要害怕使用 DbContext.Database.SqlQuery
或 DbContext.Database.ExecuteSqlCommand
. 实体框架不支持你可能想要执行的所有操作,可以在需要时绕过它。