[英]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.