SETUP
我有一个"订单" class和" OrderDetail"类。
Order类有一个名为" OrderDetails"类型IQueryable。
我在每个类中都有一个名为" GetData"并且此方法返回其所在类的IQueryable
" GetData"方法是实体周围的包装器,用于将实体转换为更友好的.NET类/属性
例如:OrderDetail实体有一个" PullDate"在数据库中作为Char(10)但我希望OrderDetail类具有一个名为" PullDate"的属性。这是类中DateTime的类型。
代码
public class Order
{
[Key]
public int ID { get; set; }
public IQueryable<OrderDetail> OrderDetails { get; set; }
public static IQueryable<Order> GetData()
{
IQueryable<Order> orders;
var db = new OrderEntities();
// NOTE: This code will work
try
{
var data =
(from O in db.Orders
where O.OrderID == 1
select new Order
{
ID = O.OrderID,
OrderDetails =
(from OD in db.OrderDetails
where OD.OrderID == O.OrderID
select new OrderDetail
{
ID = OD.OrderDetailID,
OrderID = OD.OrderID,
PullDate = OD.PullDate == "00000000" ?
(DateTime?)null : db.yyyyMMddToDate(OD.PullDate),
Description = OD.Desc
})
});
orders = data.AsQueryable();
var orderList = orders.ToList();
}
catch (Exception ex)
{
throw;
}
// NOTE: This code will NOT work
try
{
var data = (from O in db.Orders
where O.OrderID == 1
select new Order
{
ID = O.OrderID,
OrderDetails = (from OD in OrderDetail.GetData(db)
where OD.OrderID == O.OrderID
select OD)
});
orders = data.AsQueryable();
var orderList = orders.ToList();
}
catch (Exception ex)
{
throw;
}
return orders;
}
}
public class OrderDetail
{
[Key]
public int ID { get; set; }
public int OrderID { get; set; }
public DateTime? PullDate { get; set; }
public string Description { get; set; }
public static IQueryable<OrderDetail> GetData(OrderEntities db)
{
IQueryable<OrderDetail> orderDetails;
var data = (from OD in db.OrderDetails
select new OrderDetail
{
ID = OD.OrderDetailID,
OrderID = OD.OrderID,
PullDate = OD.PullDate == "00000000" ?
(DateTime?)null : db.yyyyMMddToDate(OD.PullDate),
Description = OD.Desc
});
orderDetails = data.AsQueryable();
var orderList = orderDetails.ToList();
return orderDetails;
}
}
错误
LINQ to Entities无法识别方法&#39; System.Linq.IQueryable`1 [Models.OrderDetail] GetData(Models.OrderEntities)&#39;方法,并且此方法无法转换为商店表达式。
请求
我希望Order.GetData方法使用LINQ调用OrderDetail.GetData方法
我需要加入&#34; GetData方法在一起或&#34; sub select&#34;在Order.GetData类中的OrderDetail.GetData
这两个类都在其GetData方法中查询EntityFramework
预测是一项要求
我的目标是创造&#34;可重复使用&#34;方法如&#34; GetData&#34;在我的DTO类中将包含特定的SQL /实体逻辑
例如,我使用了许多自定义SQL函数,例如&#34; db.yyyyMMddToDate&#34;在我的DTO课程中,将实体转换为更加对象/ .NET友好的东西,我不想重新输入&#34;每次我需要的所有逻辑&#34;加入/子选择&#34;来自实体的数据。
在LINQ to Objects中,这与从不同的类加入两个不同的列表相同
但似乎LINQ to Entity不知道如何从其他类连接方法,即使该方法被标记为可查询。
我知道LINQ to Entity正在处理&#34; GetData&#34;方法好像它们是SQL函数,但我需要一种方法来告诉LINQ to Entity这些只是更多的实体连接在一起以获得结果。
答案 0 :(得分:1)
你得到这个错误,因为在处理LINQ to Entities时,你没有像在LINQ to Object中那样将lambdas传递给LINQ运算符。你正在传递表达树。您在这些查询中编写的代码将永远不会被执行。它将被实体框架解释为一系列转换为SQL等其他语言的指令。
GetData
方法在SQL中没有任何意义。事实上,它并不意味着你自己的程序之外的任何东西。这就是LINQ to Entities无法将您的方法识别为有效构造的原因。
要在类似您的方案中访问订单的详细信息,您需要构建查询,以便EF知道使用Include运算符在主查询中包含OrderDetails实体。执行此操作时,EF希望您的对象具有与此类似的属性:
public virtual ICollection<OrderDetail> OrderDetails { get; set; }
这就是EF将如何知道从包含这些元素的查询中生成对象的位置。
var ctx = new DatabaseContext();
var query = ctx.Orders
.Where(o => o.OrderId == 1)
.Include(o => o.OrderDetails);
此查询将向远程服务器请求OrderId为1的所有订单及其所有匹配的OrderDetails。然后,EF将自动为您创建所有相关的客户端实体。
以下是EF关于此主题的官方文档:http://msdn.microsoft.com/en-ca/data/jj574232.aspx