每次我使用Include扩展名时,如果在 WHERE CLAUSE 中使用了包含实体的值,它将返回一个错误。
我加入了 System.Data.Entity ,这是常见的答案,但仍然存在相同的问题。
型号:
public partial class business_partner
{
public int id { get; set; }
public string accountid { get; set; }
}
public partial class order
{
public int id { get; set; }
public string doc_number { get; set; }
public int vendor_id { get; set; }
public int status { get; set; };
[ForeignKey("vendor_id")]
public virtual business_partner businessPartnerVendor { get; set; }
}
public IQueryable<order> GetOrder()
{
return (context.order);
}
查询:
_orderService.GetOrder()
.Include(a => a.businessPartnerVendor)
.Where(o => o.doc_number == "Order Number"
&& o.businessPartnerVendor.accountid == "TEST"
&& o.status > 2 && o.status != 9).Count() > 0
例外:
LINQ to Entities不支持指定的类型成员'businessPartnerVendor'。仅支持初始化程序,实体成员和实体导航属性。
答案 0 :(得分:2)
las,您忘记写您的要求了。您的代码无法满足您的要求,因此我可能得出错误的结论,但是在您的代码中,您似乎需要以下内容:
告诉我是否有
Orders
,
-值DocNumber
等于“ Order_Number”,
-AND是BusinessPartnerVendor
的值为AccountId
等于“ TEST”的订单,
-AND的值Status
大于2且不等于9。
部分“告诉我是否有Orders
”是因为您只想知道是否Count() > 0
您的计数将连接所有元素,包括BusinessPartnerVendor的所有列,删除与您的“位置”不匹配的所有行,并计算剩余的连接项数。该整数值将被传输,然后您的进程将检查该值是否大于零。
数据库查询的最慢部分之一是将所选数据从数据库管理系统传输到本地进程。因此,限制传输的数据量是明智的。
我经常看到人们使用Include
来获取存储在不同表中的项目(通常是一对多)。这将选择完整的行。在businessPartnerVendor中,您只想使用属性AccountId
。那为什么选择完整的对象呢?
在实体框架中,使用“选择”选择要查询的属性。仅在要更新获取的数据时才使用“包含”。
bool areTestOrdersAvailable = orderService.GetOrder()
.Where(order => order.doc_number == "Order Number"
&& order.businessPartnerVendor.accountid == "TEST"
&& order.status > 2 && order.status != 9)
.Any();
由于类中使用了virtual关键字(可能是一些流利的API),所以实体框架知道一对多关系并将为您执行正确的联接。它将仅使用SQL“ TAKE 1”来检测是否有任何元素。只能传送一个布尔值
有关实体框架的一些建议
优良作法是尽可能多地坚持the entity framework code first conventions,这是您做的越多,所需的属性和Fluent API越少。微软使用的类,字段,属性,方法等标识符与您的标识符之间的差异也将减少。
在实体框架中,表的所有列均由非虚拟属性表示,虚拟属性表示表之间的关系(一对多,多对多,...)
我的建议是:将外键添加到类中,并坚持使用一个标识符来描述表中的一行。
因此,如果实际上是同一种东西,请决定使用business_partner
还是BusinessPartnerVendor
添加外键:
// Every Order is the Order of exactly one BusinessPartner, using foreign key (one-to-many)
public int BusinessPartnerId {get; set;}
public virtual BusinessPartner BusinessPartner {get; set;}
这样做的好处是,如果您要选择具有一个或多个Orders
的所有BusinessPartner的ID,则无需执行联接:
var businessPartnerIds = myDbContext.Orders
.Where(order => ...)
.Select(order => order.BusinessPartnerId)
.Distinct();
将仅访问一个数据库表