繁体   English   中英

封装LINQ select语句

[英]Encapsulating LINQ select statement

我有看起来像这样的LINQ语句:

return ( from c in customers select new ClientEntity() { Name = c.Name, ... });

我希望能够将select抽象到自己的方法中,这样我可以有不同的“ mapping”选项。 我的方法需要返回什么?

实质上,我希望我的LINQ查询看起来像这样:

return ( from c in customers select new Mapper(c));

编辑:

这是用于LINQ to SQL。

现在有新的答案,我注意到这是Linq to SQL ... :)

如果您查看适用于IQueryable<T>的Select版本,那么它并不需要Func<In, Out> 相反,它需要一个Expression<Func<In, Out>> 编译器知道如何从lambda生成这样的东西,这就是为什么您的常规代码可以编译。

因此,要通过将各种传递给Select的函数来准备使用各种选择映射函数,可以这样声明它们:

private static readonly Expression<Func<CustomerInfo, string>> GetName = c => c.Name;

private static readonly Expression<Func<CustomerInfo, ClientEntity>> GetEntity = c => new ClientEntity { Name = c.Name, ... };

然后,您将像这样使用它们:

var names = customers.Select(GetName);

var entities = customers.Select(GetEntity);

您可能必须使用链接方法而不是LINQ语法,然后才能传入您指定的各种Expression < Func<TSource, TResult> >值中的任何一个:

Expression<Func<CustomerTable, Customer>> someMappingExpression = c => new Customer { Name = c.Name };
return context.CustomerTable.Select(someMappingExpression);

更新: Select接受 Func ,而不是 Expression
更新:应该使用的Select函数确实采用了Expression<Func> ,而不仅仅是Func

这是用于linq的对象吗? 还是对linq感兴趣?

因为...选择新的Mapper(c),因此要求“ c”已经物化为对象,然后传递给Mapper()CTor。 (因为在数据库级别不知道“ c”,而仅在.NET级别知道)

顺便说一句:仅当您要在单独的查询子句(例如“选择”)中使用代码的“分解”部分时,此处介绍的解决方案才有效。 如果您想将它用作还做其他事情的子句的一部分(也许返回带有其他信息的匿名类型),则需要使用Expression.Xyz方法动态地构建整个表达式树。

或者,您可以使用此技巧来嵌入我在这里描述的lambda表达式:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM