我有一个与实体框架映射的LINQ查询,如下所示:
image = this.Context.ImageSet
.Where(n => n.ImageId == imageId)
.Where(n => n.Albums.IsPublic == true)
.Single();
返回单个图像对象并按预期工作。
但是,此查询返回数据库中我的Image表的所有属性。 在正常情况下,这样会很好但是这些图像包含很多需要很长时间才能返回的二进制数据。
基本上,在当前状态下我的linq查询正在执行:
Select ImageId, Name, Data
From Images
...
但我需要一个执行此instread的查询:
Select ImageId, Name
From Images
...
注意我想加载除Data之外的所有内容。 (我可以在第二次异步传递中获取此数据)
答案 0 :(得分:8)
不幸的是,如果使用LINQ to SQL,则没有最佳解决方案。
您有3个选项:
我喜欢LINQ to SQL,但就是这样。
我唯一的解决方案是重构DataBase,将所有大型数据移动到一个单独的表中,并从Image表链接到它。
这种方式在返回Image时,您只返回新DataID字段中的一个键,然后您就可以在需要时访问那些较重的数据。
欢呼声
答案 1 :(得分:1)
这将创建一个只包含那些字段的新图像。当您返回获取所选图像的数据时,我建议继续获取完整数据集,而不是尝试将其与现有ID /名称数据合并。 id / name字段相对于数据可能很小,代码比尝试合并要简单得多。此外,可能没有必要实际构造一个Image对象,使用匿名类型也可能适合您的目的。
image = this.Context.ImageSet
.Where(n => n.ImageId == imageId)
.Where(n => n.Albums.IsPublic == true)
.Select( n => new Image { ImageId = n.ImageId, Name = n.Name }
.Single();
答案 2 :(得分:1)
[如果使用Linq 2 SQL]在DBML设计器中,有一个选项可以使各个表列延迟加载。对于大型二进制字段,将此设置为true。然后,在实际使用之前不会加载该数据。
[问题大家:有谁知道实体框架是否支持MSVS 2010中延迟加载的varbinary / varchar? ]
解决方案#2(对于实体框架或linq 2 sql):
创建仅包含主键和varchar(max)/ varbinary(max)的表视图。将其映射到EF。
在Entity Framework设计器中,从表定义中删除varbinary(max)/ varchar(max)属性(仅在视图中定义它)。这应该将字段从读/写操作排除到该表,尽管您可以使用记录器验证该字段。
通常,您将通过排除数据blob的表访问数据。当您需要blob时,从视图中加载一行。我不确定你是否能够写入视图,我不确定你会怎么写。您可以写入视图,或者可能需要编写存储过程,或者可以为一个表清除DBML文件。
答案 3 :(得分:1)
至少现在你不能用 LINQ 来做...
我知道的最佳方法是为没有大字段的表格创建View
,并使用 LINQ 和View
。
答案 4 :(得分:0)
或者,您可以在查询表达式中使用select new ...
var image =
(
from i in db.ImageSet
where i.ImageId == imageId && i.Albums.IsPublic
select new
{
ImageId = i.ImageId,
Name = i.Name
}
).Single()
LINQ查询表达式实际上在编译时转换为Lambda表达式,但我通常使用查询表达式,因为我发现它更易读和易懂。
谢谢:)