5

我有一个图像为 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”开头的杂草。

4

1 回答 1

12

在实体框架中,如果您想在不首先获取实体的情况下进行更新,您应该能够使用如下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.SqlQueryor DbContext.Database.ExecuteSqlCommand。Entity Framework 不支持您可能想要做的所有事情,并且可以在需要时绕过它。

于 2013-10-09T15:34:38.767 回答