【发布时间】:2010-07-07 15:54:46
【问题描述】:
我正在使用 LINQ-to-Entities。使用以下查询:
var x = from u in context.Users select new { u.Id, u.Name };
仅选择Id 和Name 列。伟大的。
我正在尝试创建一个可以将 new { u.Id, u.Name} 作为参数传递的存储库,以允许客户端选择在 SELECT 语句中使用哪些列。
我正在尝试在我的存储库中使用“流利”界面而不是查询语法。基本上最后的调用是将 IQueryable 转换为 IList 并实际执行代码。我查看了 DynamicExpressions 库,但我不确定这是我想要采取的路线。使用查询语法可以做到,但流畅的界面不行?
编辑:对不起,我应该提到所有查询都封装在存储库中内部。因此,例如,我希望能够公开如下方法:
public void Project(Expression<Func<TEntity, TEntity>> fields)
{
this.Projection = fields;
}
所以调用它就像:
using (DBContext context = new DBContext())
{
IUserRepository repo = new UserRepository(context);
repo.Project(u => new { u.Id, u.Name });
repo.GetById(100);
}
GetById 的内部类似于ctx.Users.Where(u => u.Id == id).Select(this.Projection)。
这样,调用代码可以选择返回哪些列。这样做的原因是因为也许我想返回一个 User 对象,但也许我只需要 Id 和 Name(因此通过网络返回的数据更少)。
问题是我显然无法将匿名类型转换为 User。如果我能做这样的事情会很酷:
repo.Project(u => new User() { Id = u.Id, Name = u.Name });
这意味着我不需要在类型上创建匿名。编辑:好的,这似乎只在返回的类型是 POCO 时才有效......呃。
EDIT2:我可能不得不采用 LINQ 方法。我在想的是拥有Expression<Func<TEntity, object>>(使用匿名类型),然后使用反射来获取属性列表。然后,使用 LINQ 构建一个字符串表达式。唯一的缺点是我真的不想使用 LINQ,因为它会增加一点开销(Reflection.Emit 等)。
【问题讨论】:
-
为什么您试图将投影放入存储库中?你最好返回一个 IQueryable
。然后,任何人都可以选择他们喜欢的任何列,并且惰性评估将负责使其在通过网络传输的内容方面变得高效。 -
我不希望我的存储库因 IQueryable
而泄漏。见stackoverflow.com/questions/718624/…
标签: c# linq linq-to-entities