C# Linq多对多关系联接

C# Linq多对多关系联接,c#,linq,entity-framework,linq-to-sql,C#,Linq,Entity Framework,Linq To Sql,我有4个表,UserCredential、UserProfile、UserRoles和Role UserRole有UserId和RoleId,所以用户可以有多个角色 由上述代码生成的查询似乎效率不高。有人能推荐一个更好的代码吗首先,由于我们担心性能,请确保您的数据库在所有这些UserId和RoleId列上都有索引 因为您有多个用户角色,将其包含在联接中会浪费地增加查询的基数,然后调用FirstOrDefault将其拉回一个。一您还没有展示如何选择特定的用户,但我将让您自行解决,除非在您的一个数据

我有4个表,UserCredential、UserProfile、UserRoles和Role

UserRole有UserId和RoleId,所以用户可以有多个角色


由上述代码生成的查询似乎效率不高。有人能推荐一个更好的代码吗首先,由于我们担心性能,请确保您的数据库在所有这些UserId和RoleId列上都有索引

因为您有多个用户角色,将其包含在联接中会浪费地增加查询的基数,然后调用FirstOrDefault将其拉回一个。一您还没有展示如何选择特定的用户,但我将让您自行解决,除非在您的一个数据源中对其进行过滤

此外,匿名对象上的roles属性:每次触摸它时,都会访问数据库。这很可能是性能问题的根源。如果缓存该信息是可以接受的,那么使用ToList调用完成子查询将是明智的

子查询本身可能是另一个麻烦源,特别是如果使用ToList,这将是对数据库的另一次访问,因此请确保将主查询的基数保持在较低的水平,以控制访问次数

var user = (from uc in Db.UserCredentials
            join up in Db.UserProfiles on uc.UserId equals up.UserId
            //where uc.UserId == somePassedInUserId    /* add this line if your datasources aren't filtered */
            select new {
                Credetial = uc, 
                Profile = up, 
                Roles = (from ur in Db.UserRoles join r in Db.Roles on ur.RoleId equals r.RoleId
                           where ur.UserId == uc.UserId select r).ToList()
            .FirstOrDefault();

EF自动为关系创建导航属性,所以您不需要使用联接。您可以将EF和LINQ指示给SQL。你用哪一种?每种方法生成的SQL可能非常不同。发布生成的SQL并指出您认为它效率低下的地方。无论如何,考虑把它看作是一个对象图,而不是用连接来设置,你会发现一个更好的选择。
var user = (from uc in Db.UserCredentials
            join up in Db.UserProfiles on uc.UserId equals up.UserId
            //where uc.UserId == somePassedInUserId    /* add this line if your datasources aren't filtered */
            select new {
                Credetial = uc, 
                Profile = up, 
                Roles = (from ur in Db.UserRoles join r in Db.Roles on ur.RoleId equals r.RoleId
                           where ur.UserId == uc.UserId select r).ToList()
            .FirstOrDefault();