Linq to EF 系统不支持异常 System.NotSupportedException

Posted

技术标签:

【中文标题】Linq to EF 系统不支持异常 System.NotSupportedException【英文标题】:Linq to EF system not supported exception System.NotSupportedException 【发布时间】:2013-03-30 07:30:37 【问题描述】:

在这个 Linq 查询上摸不着头脑。它是实体框架。查询将转换为不同的模型对象。如果我注释或删除我指出导致错误的代码区域,则 linq 查询将起作用。但在我看来,我应该能够编写这样的查询而不会出现此错误:

无法创建“DomainModel.Model.CustomerAddress”类型的空常量值。此上下文仅支持实体类型、枚举类型或原始类型。

谁能告诉我为什么我不能或更重要的是我需要改变什么才能让它工作?

谢谢

var orders = from o in _db.Orders
                          .Include("User")
                          .Include("OrderItems.Inventories.Product")
                          .Include("Transactions")
                          .Include("CustomerAddressBilling.Address")
                          .Include("CustomerAddressBilling.Customer")
                          .Include("CustomerAddressBilling.Contact")
                          .Include("CustomerAddressShipping.Address")
                          .Include("CustomerAddressShipping.Customer")
                          .Include("CustomerAddressShipping.Contact")
                          .Include("ShippingMethod")
                     // this works ok
                         let items = (o.OrderItems.Select(i => new Model.OrderItem
                         
                             OrderItemId = i.OrderItemId,
                             OrderId = i.OrderId,
                             DateAdded = i.CreateDate,
                             LineItemPrice = i.Inventories.Sum(ii => ii.Product.Price),
                             Product = i.Inventories.FirstOrDefault().Product,
                             Quantity = i.Inventories.Count()
                         ))
                     // this works ok
                     let transactions = (o.Transactions.Select(t => new Model.Transaction
                         
                             Id = t.TransactionId,
                             OrderId = t.OrderId,
                             Amount = t.Amount,
                             AuthorizationCode = t.AuthorizationCode,
                             DateExecuted = t.TransactionDate,
                             Notes = t.Notes,
                             Processor = (Model.TransactionProcessor)t.ProcessorId
                         ))
                     // this causes the error
                     let cab = o.CustAddBillingId.HasValue ? (new Model.CustomerAddress
                         
                             Id = o.CustomerAddressBilling.CustAddId,
                             UserName = o.User.UserName,
                             FirstName = o.CustomerAddressBilling.Customer.FirstName,
                             LastName = o.CustomerAddressBilling.Customer.LastName,
                             MiddleInitial = o.CustomerAddressBilling.Customer.MiddleName,
                             Salutation = o.CustomerAddressBilling.Customer.Salutation,
                             Suffix = o.CustomerAddressBilling.Customer.Suffix,
                             Street1 = o.CustomerAddressBilling.Address.Line1,
                             Street2 = o.CustomerAddressBilling.Address.Line2,
                             Street3 = o.CustomerAddressBilling.Address.Line3,
                             City = o.CustomerAddressBilling.Address.City,
                             StateOrProvince = o.CustomerAddressBilling.Address.State,
                             Zip = o.CustomerAddressBilling.Address.PostalCode,
                             Country = o.CustomerAddressBilling.Address.Country,
                             Latitude = o.CustomerAddressBilling.Address.Lat,
                             Longitude = o.CustomerAddressBilling.Address.Long,
                             Email = o.CustomerAddressBilling.Contact.ContactInfo,
                             IsDefault = o.CustomerAddressBilling.IsPrimary
                         ) : default(Model.CustomerAddress)
                     // this causes the error
                     let cas = o.CustAddShippingId.HasValue ? (new Model.CustomerAddress
                         
                             Id = o.CustomerAddressShipping.CustAddId,
                             UserName = o.User.UserName,
                             FirstName = o.CustomerAddressShipping.Customer.FirstName,
                             LastName = o.CustomerAddressShipping.Customer.LastName,
                             MiddleInitial = o.CustomerAddressShipping.Customer.MiddleName,
                             Salutation = o.CustomerAddressShipping.Customer.Salutation,
                             Suffix = o.CustomerAddressShipping.Customer.Suffix,
                             Street1 = o.CustomerAddressShipping.Address.Line1,
                             Street2 = o.CustomerAddressShipping.Address.Line2,
                             Street3 = o.CustomerAddressShipping.Address.Line3,
                             City = o.CustomerAddressShipping.Address.City,
                             StateOrProvince = o.CustomerAddressShipping.Address.State,
                             Zip = o.CustomerAddressShipping.Address.PostalCode,
                             Country = o.CustomerAddressShipping.Address.Country,
                             Latitude = o.CustomerAddressShipping.Address.Lat,
                             Longitude = o.CustomerAddressShipping.Address.Long,
                             Email = o.CustomerAddressShipping.Contact.ContactInfo,
                             IsDefault = o.CustomerAddressShipping.IsPrimary
                         ) : default(Model.CustomerAddress)
                     // this causes the error
                     let sm = o.ShippingMethodId.HasValue ? (new ShippingMethod
                             
                                 Id = o.ShippingMethod.ShippingMethodId,
                                 Carrier = o.ShippingMethod.Carrier,
                                 ServiceName = o.ShippingMethod.ServiceName,
                                 BaseRate = o.ShippingMethod.BaseRate,
                                 RatePerPound = o.ShippingMethod.RatePerPound,
                                 DaysToDeliver = o.ShippingMethod.DaysToDeliver,
                                 EstimatedDelivery = o.ShippingMethod.EstimatedDelivery
                             ) : default(ShippingMethod)
                     select new Model.Order
                         
                             Id = o.OrderId,
                             UserName = o.User.UserName,
                             DateCreated = o.CreateDate,
                             Items = items.AsQueryable(),
                             Transactions = transactions.AsQueryable(),
                             ShippingAddressId = o.CustAddShippingId,
                             BillingAddressId = o.CustAddBillingId,
                             // have to comment these next 3 lines as well
                             ShippingAddress = cas,
                             BillingAddress = cab,
                             ShippingMethod = sm,
                             // to here
                             UserLanguageCode = "en",
                             DateShipped = o.ShippedDate,
                             EstimatedDelivery = o.EstimatedDelivery,
                             TrackingNumber = o.TrackingNumber,
                             TaxAmount = o.TaxAmount,
                             DiscountReason = o.DiscountReason,
                             DiscountAmount = o.DiscountAmount
                         ;

【问题讨论】:

尝试用null替换default(Model.CustomerAddress) 做到了,没关系。我认为这与 cab、cas 和 sm 是对单个对象的引用而不是对集合的引用这一事实有关 一位朋友建议错误是由于 let 子句中的三元表达式。但我不知道如何摆脱它。 我也可以复制这种行为。它很奇怪。将 let 子句下移到 select 语句没有帮助。 同样的问题描述here 【参考方案1】:

好的,我想通了。问题是数据库允许对这些相关实体使用 null forien 键,我更改了数据库,因此 forien 键不可为空,并从数据库中更新了模型。我创建了代表非ShippingMethods 电子和面对面的新数据实体,并且还拥有面对面的CustomerAddress,因此我可以拥有指向数据的链接,这些数据不仅代表我没有数据,而且代表我为什么没有数据。

    public IQueryable<Model.Order> GetOrders()
    
        var orders = from o in _db.Orders
                                  .Include("User")
                                  .Include("OrderItems.Inventories.Product")
                                  .Include("Transactions")
                                  .Include("CustomerAddressBilling.Address")
                                  .Include("CustomerAddressBilling.Customer")
                                  .Include("CustomerAddressBilling.Contact")
                                  .Include("CustomerAddressShipping.Address")
                                  .Include("CustomerAddressShipping.Customer")
                                  .Include("CustomerAddressShipping.Contact")
                                  .Include("ShippingMethod")
                     let items = (o.OrderItems.Select(i => new Model.OrderItem
                         
                             OrderItemId = i.OrderItemId,
                             OrderId = i.OrderId,
                             DateAdded = i.CreateDate,
                             LineItemPrice = i.Inventories.Sum(ii => ii.Product.Price),
                             Product = i.Inventories.FirstOrDefault().Product,
                             Quantity = i.Inventories.Count()
                         ))
                     let transactions = (o.Transactions.Select(t => new Model.Transaction
                         
                             Id = t.TransactionId,
                             OrderId = t.OrderId,
                             Amount = t.Amount,
                             AuthorizationCode = t.AuthorizationCode,
                             DateExecuted = t.TransactionDate,
                             Notes = t.Notes,
                             Processor = (Model.TransactionProcessor)t.ProcessorId
                         ))
                     let cab = new Model.CustomerAddress
                         
                             Id = o.CustomerAddressBilling.CustAddId,
                             UserName = o.User.UserName,
                             FirstName = o.CustomerAddressBilling.Customer.FirstName,
                             LastName = o.CustomerAddressBilling.Customer.LastName,
                             MiddleInitial = o.CustomerAddressBilling.Customer.MiddleName,
                             Salutation = o.CustomerAddressBilling.Customer.Salutation,
                             Suffix = o.CustomerAddressBilling.Customer.Suffix,
                             Street1 = o.CustomerAddressBilling.Address.Line1,
                             Street2 = o.CustomerAddressBilling.Address.Line2,
                             Street3 = o.CustomerAddressBilling.Address.Line3,
                             City = o.CustomerAddressBilling.Address.City,
                             StateOrProvince = o.CustomerAddressBilling.Address.State,
                             Zip = o.CustomerAddressBilling.Address.PostalCode,
                             Country = o.CustomerAddressBilling.Address.Country,
                             Latitude = o.CustomerAddressBilling.Address.Lat,
                             Longitude = o.CustomerAddressBilling.Address.Long,
                             Email = o.CustomerAddressBilling.Contact.ContactInfo,
                             IsDefault = o.CustomerAddressBilling.IsPrimary
                         
                     let cas = new Model.CustomerAddress
                         
                             Id = o.CustomerAddressShipping.CustAddId,
                             UserName = o.User.UserName,
                             FirstName = o.CustomerAddressShipping.Customer.FirstName,
                             LastName = o.CustomerAddressShipping.Customer.LastName,
                             MiddleInitial = o.CustomerAddressShipping.Customer.MiddleName,
                             Salutation = o.CustomerAddressShipping.Customer.Salutation,
                             Suffix = o.CustomerAddressShipping.Customer.Suffix,
                             Street1 = o.CustomerAddressShipping.Address.Line1,
                             Street2 = o.CustomerAddressShipping.Address.Line2,
                             Street3 = o.CustomerAddressShipping.Address.Line3,
                             City = o.CustomerAddressShipping.Address.City,
                             StateOrProvince = o.CustomerAddressShipping.Address.State,
                             Zip = o.CustomerAddressShipping.Address.PostalCode,
                             Country = o.CustomerAddressShipping.Address.Country,
                             Latitude = o.CustomerAddressShipping.Address.Lat,
                             Longitude = o.CustomerAddressShipping.Address.Long,
                             Email = o.CustomerAddressShipping.Contact.ContactInfo,
                             IsDefault = o.CustomerAddressShipping.IsPrimary
                         
                     let sm = new ShippingMethod
                        
                            Id = o.ShippingMethod.ShippingMethodId,
                            Carrier = o.ShippingMethod.Carrier,
                            ServiceName = o.ShippingMethod.ServiceName,
                            BaseRate = o.ShippingMethod.BaseRate,
                            RatePerPound = o.ShippingMethod.RatePerPound,
                            DaysToDeliver = o.ShippingMethod.DaysToDeliver,
                            EstimatedDelivery = o.ShippingMethod.EstimatedDelivery
                        
                     select new Model.Order
                         
                             Id = o.OrderId,
                             UserName = o.User.UserName,
                             DateCreated = o.CreateDate,
                             Items = items.AsQueryable(),
                             Transactions = transactions.AsQueryable(),
                             ShippingAddressId = o.CustAddShippingId,
                             BillingAddressId = o.CustAddBillingId,
                             ShippingAddress = cas,
                             BillingAddress = cab,
                             ShippingMethod = sm,
                             UserLanguageCode = "en",
                             DateShipped = o.ShippedDate,
                             EstimatedDelivery = o.EstimatedDelivery,
                             TrackingNumber = o.TrackingNumber,
                             TaxAmount = o.TaxAmount,
                             DiscountReason = o.DiscountReason,
                             DiscountAmount = o.DiscountAmount
                         ;
        return orders;
    

而且没有错误!

【讨论】:

以上是关于Linq to EF 系统不支持异常 System.NotSupportedException的主要内容,如果未能解决你的问题,请参考以下文章

不支持 Linq-to-EF DateTime.ToLocalTime

LINQ to Entities 异常中不支持指定的类型成员“日期”

“LINQ to Entities 不支持 LINQ 表达式节点类型 'Invoke'” - 难倒!

LINQ to Entities 格式化日期异常 [重复]

EF 6.x,LINQ-to-SQL和原始SQL子句

为啥使用 EF / Linq to sql 创建性能不佳的查询如此容易[关闭]