实体框架 - Linq To Entities - 多对多查询问题

6

我在使用Linq To Entities时遇到了查询多对多关系的问题。我基本上是想用Linq复制这个查询:

Select * 
FROM Customer 
LEFT JOIN CustomerInterest ON Customer.CustomerID = CustomerInterest.CustomerID
LEFT JOIN Interest ON CustomerInterest.InterestID = Interest.InterestID
WHERE Interest.InterestName = 'Football'

我在网上搜索了很多,但并没有找到一个合适的例子来实现这个功能。最接近的例子是:

List<Customer> _Customers = (from _LCustomers in _CRM.Customer.Include("CustomerInterest.Interest")
                                  where _LCustomers.CustomerInterest.Any(x => x.Interest.InterestName == "Football")
                                  select _LCustomers).ToList();

这样做的问题是,如果客户有多个兴趣爱好,其中一个是“足球”,那么所有兴趣爱好都会被返回。我还看过All(),它有相反的问题,即只有当他们有一个兴趣爱好是足球时才会返回,如果他们有两个兴趣爱好,其中之一不是足球,则什么都不会返回。
有人有什么想法吗?

请查看这个问题 - https://dev59.com/-XI_5IYBdhLWcg3wEe1u 和这篇文章 - http://blogs.msdn.com/b/alexj/archive/2009/10/13/tip-37-how-to-do-a-conditional-include.aspx。 - Kniganapolke
5个回答

7

试试这个:

var result = from c in ctx.Customer
             from i in c.Interest
             where i.InterestName == "Football"
             select c;

希望这可以帮到你,
雷。

3
我不确定你想要获得什么。是一个具有顾客兴趣和兴趣的顾客清单吗?只需从顾客兴趣开始查询即可。
context.CustomerInterest.
   Where(ci => ci.Interest.InterestName == "Football").
   Select(ci => new
   {
      Customer = ci.Customer,
      CustomerInterest = ci,
      Interest = ci.Interest
   });

但是这样非常冗余。为什么不直接获取匹配的客户兴趣?
IEnumerable<CustomerInterest> customerInterests = context.CustomerInterest.
   Where(ci => ci.Interest.InterestName == "Football");

您可以不需要明确地存储其他信息,仍然可以访问它。

foreach (CustomerInterest customerInterest in customerInterests)
{
   DoSomething(customerInterest);
   DoSomething(customerInterest.Customer);
   DoSomething(customerInterest.Interest);
}

好的,这个想法是基于客户作为查询基础,通过单个数据库查询返回所有相关数据给客户端。返回的数据将被序列化并在单个WCF调用中返回给客户端(用于客户维护屏幕)。由于我们试图使客户端尽可能轻量化和通用化,因此客户端没有edmx中实体的概念,它只使用反序列化的XML并与其一起工作。我正在尝试避免使用匿名类型,并仅返回符合where子句的相关数据的Customer对象。 - JD.

2
        var results = from c in _CRM.Customer
                      from ci in c.Interests
                      join i in _CRM.Interests
                      on ci.ID equals i.ID
                      where i.Interest = "Football"
                      select c;

1
如果你想保持通用性,更好的方式是使用实体SQL[Esql]。因为L2E不支持LINQ查询中集合的where。
你不能使用
customer.Interests.Where(interest => interest.Name =='FootBall')
查询会像这样..
context.CreateQuery(@"SELECT VALUE Customer FROM Customer WHERE EXISTS( SELECT VALUE FROM CustomerInterest WHERE CustomerInterest.Ineterest.Name = 'FootBall')).Include("Interest");
希望对你有所帮助!

仅仅为了解决问题而降级到使用 ESQL,感觉不是很专业,对吧?你失去了所有的智能提示和使用 EF 的意义。这时候最好直接在 DbReader 中执行它。 - Jason Short
是的,但是在 EF 中,您会得到一个带有类型的实体客户端,而不是 ADO 中由 DbReader 返回的数据记录。 - Deepak N

0

这对于LINQT来说太多了。尝试在数据库中使用视图或按照Deepak N所说的方式工作。

最好的祝愿

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接