封装LINQ select语句

时间:2008-12-10 18:18:36

标签: c# linq linq-to-sql

我有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。

4 个答案:

答案 0 :(得分:4)

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

如果您查看适用于IQueryable<T>的选择版本,则不会使用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);

答案 1 :(得分:1)

您可能必须使用链式方法而不是使用LINQ语法,然后您将能够传递各种Expression < Func<TSource, TResult> {{1}中的任何一种您指定的值:

>

更新: Select需要Expression<Func<CustomerTable, Customer>> someMappingExpression = c => new Customer { Name = c.Name }; return context.CustomerTable.Select(someMappingExpression); ,而不是Func
更新应使用的Select功能采用Expression,而不只是Expression<Func>

答案 2 :(得分:0)

这是针对linq的对象吗?或者对于linq来说?

因为...选择新的Mapper(c),要求'c'已经实现为一个对象,然后传递给Mapper()CTor。 (因为'c'在数据库级别是未知的,仅在.NET级别)

答案 3 :(得分:0)

BTW:此处描述的解决方案仅在您希望在单独的查询子句中使用代码的“因素”部分时才有效(例如,选择)。如果你想将它作为一个子句的一部分,也可以做一些其他事情(可能返回带有其他信息的匿名类型),你需要使用 Expression.Xyz动态构建整个表达式树方法。

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