也有类似的问题,答案并不适用于我的情况。
我得到一个
无法创建类型为'. model .featureoptions'的常量值。在此上下文中只支持基本类型('如Int32, String和Guid')。
Using Entity First, EntityFramework 4.1, MVC3, c# 4.
vehicles
为车辆细节表,owners
为车主表。vehicles
和owners
是内连接的,这是有效的。
features
表是可选功能的列表,例如天窗,油漆等。featureOptions
是一个功能的可用选项列表。例如,油漆可以是"珠光","金属",天窗可以是"玻璃弹出式","标题+幻灯片"。
vehicleFeatures
是车辆的选择选项列表,对于特定的功能,车辆可以有零或一个记录。
在这个查询中,feature1
应该是null
或一个特性的选择值(即选择的天窗选项),feature2
应该是null
或另一个特性的选择值(即选择的油漆选项)
var query = (from v in _entities.vehicles
join o
in _entities.owners
on v.OwnerID equals o.OwnerID
// Some more inner joins
select new
{
// <code snipped >
// o. fields and v. fields
// </ code snipped>
feature1 = (from feature1
in _entities.vehiclefeatures
.Where ( f_1 => f_1.VehicleID == v.VehicleID)
join feature1_fo
in _entities.featureoptions
on feature1.FeatureOptionID equals feature1_fo.FeatureOptionID
join feature1_f
in _entities.features
.Where (bt_f => bt_f.CodeEnum==1)
on feature1_fo.FeatureID equals feature1_f.FeatureID
select new featureoptionsDTO () { Option = feature1_fo.Option }
),
feature2 = (from feature2
in _entities.vehiclefeatures
.Where(f_2 => f_2.VehicleID == v.VehicleID)
join feature2_fo
in _entities.featureoptions
on feature2.FeatureOptionID equals feature2_fo.FeatureOptionID
join feature2_f
in _entities.features
.Where(feature2_f => feature2_f.CodeEnum == 2)
on feature2_fo.FeatureID equals feature2_f.FeatureID
select new featureoptionsDTO() { Option = feature2_fo.Option }
)
}
);
foreach (var vehicle in query) // Exception here
{
}
feature1 = (from ..
和
feature2 = (from ..
导致
无法创建类型为'. model .featureoptions'的常量值。在此上下文中只支持基本类型('如Int32, String和Guid')。
我知道LINQ试图创建一个实体,我怎么能让它创建一个匿名(或自己的类)代替?
不幸的是,实体框架不能处理在LINQ to Entities查询中构造任意类型的select子句。我自己也被这个问题绊倒过几次,这很烦人。然而,这是非常必要的,因为LINQ到实体的查询被转换成SQL在数据库上运行,而数据库不能处理。net对象的构造。如果能在查询的末尾这样做可能会很好,但是绝对不能在查询的中间这样做。
我倾向于做的是编写一个查询,该查询准确地生成了LINQ to Entities中构造器所需的输入,以便它在数据库上运行。然后在IQueryable上调用ToEnumerable(),它会把它变成一个IEnumerable,然后在LINQ to Objects中,你可以在Select()中做任何你喜欢的事情。
我通过使用数据库中的视图进行外连接和linq查询与该视图关联的实体来解决这个问题。
通过在数据库中执行左外操作意味着外部连接更早完成,可能会使其更快一些。linq更整洁,只需要做它需要做的事情,在本例中是过滤。