0

我不使用linq。我使用 EF 4.0。我总是使用 lambda 表达式来获取我的数据,如下所示:

List<User> users = db.Users
                        .Include(u => u.Licences)
                        .Include(u => u.Licences.Select(l => l.LicenceProducts.Select(lp => lp.Product)))
                        .Include(u => u.UserAddress)
                        .Include(u => u.Contact)
                        .Include(u => u.User2)
                        .Include(u => u.SupportProducts)
                        .Where(u => u.Type != (int)UserType.Admin)
                        .OrderBy(u => u.Name)
                        .ToList();

不幸的是,它需要很多时间来执行。所以,我想通过使用左连接来改变它,但我没有正确理解连接在 Linq 中的工作方式。

这是我尝试过的:

users = from user in db.Users
        join licence in db.Licences on user.UserID equals licence.UserID
        join licenceProduct in db.LicenceProducts on licence.LicenceID equals licenceProduct.LicenceID...;

它返回的类型与以前不同(列表)

我也试过这个,但我有同样的问题

users = db.Users
    .Join(db.Licences, lic => lic.UserID, user => user.UserID, (user, lic) => new { user, lic })
4

2 回答 2

2

Joins don't do the same as Include. Includes tell EF to populate associated navigation properties off the entity that's in the main query. Joins, however, only execute a SQL joins, but don't populate anything.

You typically use joins if you want to filter on properties in child or parent objects. Like join c in Contacts ... where c.Name == "..." – this only returns Users without any contacts populated. The SQL SELECT clause only contains User columns. (Well, assuming you only select distinct users).

Includes also produce SQL joins, but at the same time put all columns of the included entities in the SELECT clause. The query result set is used to materialize all included entities. When there are many Includes, this result will blow up incredibly in width and length. In width, because it selects all columns of all included entities. In length because each included child collection multiplies the result set by its number of rows.

Therefore it is recommended to have no more than three Includes. So I think you have to reconsider the number of Includes you really need. It's probably much more efficient to load associated entities in separate queries.

于 2013-11-04T18:16:46.463 回答
1

您使用的联接是内部联接,而不是左联接。您可以使用DefaultIfEmpty()将它们变成左连接,如下所述:http: //msdn.microsoft.com/en-us/library/vstudio/bb397895.aspx

另外,请注意,使用 linq 您正在创建一个查询,而不是一个列表。只有在需要检索结果时才会执行查询。你可以打电话ToList()来做这件事。一般来说,如果您使用 LINQ 来检索数据,那么阅读有关延迟执行的信息很重要(这里有很好的解释:http: //blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution。 aspx),否则如果在创建查询和执行查询之间发生变化,您获得的数据可能不是您所期望的。

此外,对于这么多包括我认为使用存储过程更容易。

于 2013-11-04T17:13:36.020 回答