我有一个表格,其图像为varbinary(max),另一个数据(另一种类型)更紧凑。我想更新另一个数据但不更新图像。在循环(即所有记录)中使用过滤器来选择要更新的记录。我找到了各种解决方案,但是所有这些解决方案都使用将整个记录提取到上下文中或将现有记录(即先前提取或创建)附加到上下文。说“在之前的某个时间取出或创建”我的意思是所有字段的整个记录都显示出来 - 不是剪切图像或其他“不必要的”字段。
有没有办法更新记录而不通过EF获取任何不必要的数据(例如varbinary图像)?也许只是在没有所有字段的情况下获取任何轻量级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
)
EF的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”开头的杂草,例如。
答案 0 :(得分:12)
在Entity Framework中,如果您想在不先获取实体的情况下进行更新,您应该可以使用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
。实体框架不支持您可能想要做的所有事情,并且可以在需要时绕过它。