我可以在加入中使用委托变量并获得IQueryable

时间:2014-09-04 23:06:39

标签: c# linq-to-sql delegates

来源

我有一个LINQ-to-SQL查询,根据外部标准略有不同。我为三种不同的情况编写了一个switch语句,但是在不同情况下的一系列查询几乎完全相同。唯一不同的是用于连接条件的委托。

因此,为了使我的代码DRYer,我决定只使用switch语句从三个不同的委托中进行选择。然后我将所选择的delagate保存在变量中,并在.Join调用中使用该变量。

问题

但是,当我使用变量而不是显式地键入委托时,.Join不再返回IQueryable,而是返回IEnumerable。我应该澄清一下,我从' var'中获取Intellisense的返回值。关键字。

所以这个返回一个IQueryable:

var dc = new CloudDataContext();
var manifests = dc.ShippingManifests.Join(
    dc.Locations,
    man => man.OriginId,
    loc => loc.Id,
    (man, loc) => man
);

但是这个返回一个IEnumerable:

protected static int? ManifestOriginId( ShippingManifest manifest ) {
    return manifest.OriginId;
}

Func<ShippingManifest, int?> originJoiner = GridModelManifests.ManifestOriginId;

var dc = new CloudDataContext();
var manifests = dc.ShippingManifests.Join(
    dc.Locations,
    originJoiner,
    loc => loc.Id,
    (man, loc) => man
);

问题

我很好奇为什么会这样,但我更好奇我如何才能完成我想要完成的事情。我需要获得一个IQueryable,因为生成的查询将被传递到线上以进行进一步操作。

1 个答案:

答案 0 :(得分:1)

尝试Expression

如果不是,查询可能会被水合并在加入之前被拉入内存。您所追求的是Expression<Func<ShippingManifest, int?>>

Expression<Func<ShippingManifest, int?>> originJoiner = man => man.OriginId;

这允许Linq to SQL中的表达式访问者在将其发送到数据库之前继续处理它。