【问题标题】:Entity Framework many-to-many conditional join实体框架多对多条件连接
【发布时间】:2012-06-12 01:22:56
【问题描述】:

现在我有 3 个表:用于多对多关联的 User、Roles 和 User_Roles。我想创建一个搜索函数,该函数接受一个 RoleID 列表并返回具有该角色的用户。但如果 RoleID 列表为空,则应该返回所有用户

这是我目前所拥有的......

public static List<User> SearchUser(List<int> roleIDs)
{
    List<User> userList = new List<User>();
    using (var db = new DBContext())
    {
        var users = (
            from u in db.Users
            join ur in db.User_Role
                on u.UserID equals ur.UserID
            join r in roleIDs
                on ur.RoleID equals r
            select u
            ).Distinct().ToList();
    }
    return userList;
}

但我无法找到一种方法来有条件地加入 User_Role,仅当 roleIDs 不为空时。

我也试过了,但是没用。

var users = (from u in db.Users
             from r in roleIDs
             join ur in db.User_Role
                 on u.UserID equals ur.UserID
             where roleIDs.Count == 0 || ur.RoleID == r
             select u
                ).Distinct().ToList();

是否可以在实体框架中进行条件连接?

【问题讨论】:

    标签: c# entity-framework


    【解决方案1】:

    分别处理每个案例。

    public static List<User> SearchUser(List<int> roleIDs)
    {
        using (var db = new DBContext())
        {
            if (roleIDs.Count == 0)
            {
                 return db.Users.ToList();
            }
    
            var users = (
                from u in db.Users
                join ur in db.User_Role
                    on u.UserID equals ur.UserID
                join r in roleIDs
                    on ur.RoleID equals r
                select u
                ).Distinct().ToList();
    
            return users;
        }
    }
    

    如果连接表未映射为单独的实体,您可以按如下方式简化连接。

    public static List<User> SearchUser(List<int> roleIDs)
    {
        using (var db = new DBContext())
        {
            if (roleIDs.Count == 0)
            {
                 return db.Users.ToList();
            }
    
            var users = db.Users.Where(u => u.Roles.Any(r => roleIDsContains(r.Id)))
                .Distinct().ToList();
    
            return users;
        }
    }
    

    【讨论】:

    • 谢谢埃兰加。我想到了使用 if 语句,但实际上,该函数将能够采用多个列表参数来进一步过滤搜索。对于空列表和非空列表的所有组合,使用 if 语句将很快开始变得混乱。这就是为什么我认为条件连接是最优雅的方式。
    • 我将您的回复标记为答案,因为从技术上讲,if 语句是可行的方法。我只是改变了逻辑。查看我发布的回复。
    【解决方案2】:

    我最关心的是在添加新的搜索条件时保持代码的可维护性,并尽量减少数据库调用。我最终使用了 if 语句,但直到最后才从数据库中加载它。这导致了一个大的发送查询。我最后通过调用.ToList() 来强制调用数据库。

    public static List<user> SearchUser(List<int> roleIDs, List<int> hobbyIDs)
    {
        List<User> Users = new List<User>();
        IQueryable<User> tempUsers = null;
        using (var db = new DBContent())
        {
            tempUsers = db.Users;
    
            if (roleIDs.Count > 0)
            {
                tempUsers = from u in tempUsers
                            join ur in db.User_Role on u.UserID equals ur.UserID
                            join r in roleIDs on ur.RoleID equals r
                            select u;
            }
    
            if (hobbyIDs.Count > 0)
            {
                tempUsers = from u in tempUsers
                            join uh in db.User_Hobby on u.UserID equals uh.UserID
                            join h in hobbyIDs on uh.HobbyID equals h
                            select u;
            }
    
            //Go get it from the database
            Users = ((ObjectQuery<User>)tempUsers)
                .Include("Address").Distinct().ToList();
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多