【问题标题】:Not supported in LINQ to EntitiesLINQ to Entities 不支持
【发布时间】:2019-01-10 07:02:35
【问题描述】:

每次我使用 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”。仅支持初始化器、实体成员和实体导航属性。

【问题讨论】:

  • “它会坏掉”是什么意思?
  • 是的,有什么错误?
  • @GeorgiGeorgiev 我为我的任期道歉。但我的意思是它会引发错误。
  • @John 错误是“LINQ to Entities 不支持指定的类型成员'businessPartnerVendor'。仅支持初始化程序、实体成员和实体导航属性。”

标签: c# entity-framework linq


【解决方案1】:

唉,你忘了写你的要求。你的代码没有做你想做的事,所以我可能会得出错误的结论,但看看你的代码,你似乎想要以下内容:

告诉我有没有Orders,那个
- 具有等于“Order_Number”的DocNumber 值,
- AND 是 BusinessPartnerVendor 的订单,其值为 AccountId 等于“TEST”,
- AND 的值为Status,大于 2 且不等于 9。

“告诉我有没有Orders那个”这部分,是因为你只想知道有没有Count() &gt; 0而被扣掉

您的 Count 将连接所有元素,包括 BusinessPartnerVendor 的所有列,删除与您的 Where 不匹配的所有行,并计算剩余的连接项目数。该整数值将被传输,之后您的进程将检查该值是否大于零。

数据库查询中较慢的部分之一是将所选数据从数据库管理系统传输到本地进程。因此,明智的做法是限制传输的数据量。

我经常看到人们使用Include 来获取存储在不同表中的项目(通常是一对多)。这将选择完整的行。在businessPartnerVendor 中,您只想使用属性AccountId。那么为什么要选择完整的对象呢?

在实体框架中使用 Select 来选择要查询的属性。如果要更新获取的数据,请仅使用 Include。

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 的 BusinessPartners 的 ID ...,您不必执行联接:

var businessPartnerIds = myDbContext.Orders
    .Where(order => ...)
    .Select(order => order.BusinessPartnerId)
    .Distinct();

只会访问一张数据库表

【讨论】:

    猜你喜欢
    • 2014-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多