使用LINQ to Entities创建具有嵌套对象列表的对象

时间:2012-01-23 19:04:25

标签: linq entity-framework

我正在尝试使用Linq to Entity Framework创建一个包含对象列表的对象。但我得到NotSupported异常。我的数据库结构与LinqPad附带的数据库非常相似。我们以此为例 - 我有一个customer域对象和Purchase(或者对于ex-Order)域对象。

Public Class Customer (){ long CustID ,string CustName , List<Purchase> purchases }
Public Class Purchase () { long PurchaseID}

我正在尝试使用像这样的导航属性填充DAL中的Customer域对象 -

db.Customer
.Where( t=> t.CustID==1)  //hard coding for 1
.Select( t=> new Customer()
{
CustName = t.name ,
Purchases = t.Customer.Purchase
        .Select ( p=> new Purchase()
            {
                PurchaseID=p.purchaseid
}).ToList()
});

我得到了此{/ p>的NotSpported例外

我还尝试为purchases – GetPurchases()创建方法。它返回购买清单并将其分配给我正在创建的客户对象。但我仍然得到同样的例外。 我收到NotSuuported异常,错误消息 -

  

无法将方法转换为存储表达式

。我搜索过,似乎它支持linq到sql但不支持linq到ef。我想尝试像这篇文章一样做同样的事情 - Using linq to return an object with a list<object> member 是否可以像我一样填充域对象。是否有任何已知的解决方案或解决此问题。

3 个答案:

答案 0 :(得分:1)

以下是类似内容的实例。在这种情况下,它是正在填充的嵌套Taxes集合。

public async Task<IEnumerable<ServiceLayer.DTO.Vendor>> GetAllVendors()
{
    return await (

        from vendor in _db.Vendors

        select new ServiceLayer.DTO.Vendor()
        {
            Id = vendor.Id,
            Name = vendor.Name,
            Taxes = (from tax in _db.VendorTaxes
                     where tax.VendorId.Equals(vendor.Id)
                     select new DTO.VendorTax() { Id = tax.Id, Rate = tax.Rate })
        })

    .ToListAsync();
}

答案 1 :(得分:0)

无法转换:

.Select ( p=> new Purchase()
            {
                PurchaseID=p.purchaseid
})

到正确的sql语句,实际上它会使表达式树,但不能将其转换为sql命令,你可以这样做:

db.Customer
.Where( t=> t.CustID==1)  //hard coding for 1
.Select( t=> new Customer()
{
CustName = t.name ,
Purchases = t.Customer.Purchase
        .Select ( p=> p.purchaseid)
        .ToList() // here you should fetch your data from DB

        // now convert fetched data via linq2object to what you want:
        .Select( p => new Purchase()
            {
                PurchaseID=p.purchaseid
            })
        .ToList();

编辑:抱歉,我没有看到您的第一个选择声明:

Select( t=> new Customer()
{
 CustName = t.name ,
 Purchases = t.Customer.Purchase...
}

linq2entity也无法处理(事实上任何复杂的初始化)

但正如我所看到的,似乎你只有一个顾客,为什么你没有完全得到它?实际上是这样做的:

var customer = db.Customer.FirstOrDefault(x=>x.ID == 1)

答案 2 :(得分:0)

您无法在Select语句中实例化模型的实体。 Select用于创建具有“selected”属性/列的对象 - 匿名对象或(例如)View Models或Data Transfer Objects。

您尝试加载的内容(包含导航属性的实体)通常是在急切加载时完成的:

var customer = db.Customer.Include("Purchases")
    .SingleOrDefault(c => c.CustID == 1);

您通常也无法在LINQ to Entities查询中使用自定义方法(如GetPurchases())。只有少数例外 - 例如IQueryable<T>的扩展方法或返回Expression<Func<T>>的方法。在大多数情况下,实体框架无法将此类自定义方法转换为数据库可以理解的语言的“存储表达式”(例如,SQL)。