我使用 ADO.NET C# POCO Entity Generator Visual Studio 加载项为我的实体生成 POCO 类。
当我尝试在 Linq to Entities 查询中使用该类时,如下所示:
var q = from w in entities.Widgets
select new Widget
{
Id = w.Id,
WidgetName = w.WidgetName,
WidgetDescription = w.WidgetDescription
};
return q.ToList();
我收到以下异常:
“实体或复杂类型 MyNamespace.Widget' 无法在 LINQ to Entities 查询中构造”。
解决这个问题的唯一方法是使用匿名类型,然后使用另一个 LINQ 查询:
var q = from w in entities.Widgets
select new
{
Id = w.Id,
WidgetName = w.WidgetName,
WidgetDescription = w.WidgetDescription
};
var r = from e in q.AsEnumerable()
select new Widget
{
Id = e.Id,
WidgetName = e.WidgetName,
WidgetDescription = e.WidgetDescription
};
return r.ToList();
这可行,但相当多余。我明白为什么我会遇到异常,但是有没有更优雅的方法来解决这个问题?
POCO 类是由 ADO.NET C# POCO 实体生成器生成的事实似乎与该问题无关;我尝试使用自己的 POCO 类并看到了相同的异常。
非常感谢。
编辑: 添加了使用 ADO.NET C# POCO 实体生成器 Visual Studio 加载项演练的链接 - http://blogs.msdn.com/b/adonet/archive/2010/01/25/walkthrough-poco-template-for-the-entity-framework.aspx
最佳答案
我猜 MyNamespace.Widget
是一个自定义类 - 并且不是 EDM 的一部分?
如果是这样,则无法将 LINQ-Entities 查询投影到自定义类型中。您是否使用 POCO 并不重要。
您对转换到匿名类型有正确的想法。
在服务器上具体化查询后,您可以在客户端上调整查询:
var widgets = entities
.Widgets
.ToList() // materialize query
.Select(x => new Widget
{
Id = w.Id,
WidgetName = w.WidgetName,
WidgetDescription = w.WidgetDescription
}
).ToList();
这比您的解决方法好一点。
但这引出了一个问题 - 为什么不首先在 EDM 上返回“Widget”类型?
POCO 的全部意义在于,您可以将持久性逻辑分成简单的类。所以我不确定为什么你从一个简单类型(POCO)投影到另一个(看似相同)简单类型。您是否将 POCO 映射到 DTO 以进行 N 层传输?
关于entity-framework - 使用生成的 POCO 类的 EF4 中的 Linq to Entities,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4504597/