实体框架:更好的方法做多对多查询?

时间:2015-10-30 13:26:47

标签: asp.net-mvc performance entity-framework linq

环境:首先是EF6代码

我有两个表,例如useractivity,它们具有多对多的关系。

我想在asp.net mvc应用程序中使用Entity Framework知道任何用户的活动是否具有给定密钥。

  1. 明智的是以下查询性能?

  2. 有没有其他方法可以编写此查询?

  3. 查询:

    var userEntity = _dbcontext.Users.Find(userId);
    
    var isAvailable = _dbcontext.Entry(userEntity)
                                .Collection(e => e.Activities)
                                .Query().Any(e => e.Name== "givenname");
    

    更新

    我运行了这些查询,现在是时候运行了:

    1

    var userEntity = _dbcontext.Users.Find(userId);
    
    var isAvailable = userEntity.Activities.Any(a => a.Name == "givenname");
    

    时间:5.39s +获取用户的时间

    2

    var isAvailable =_dbcontext.Users.Include(e => e.Activities)
                                 .Any( u => u.UserId == userId 
                                        &&  u.Activities.Any(a => a.Name == "givenname")
                                     );
    

    时间:5.73s

    第3

    var userEntity = _dbcontext.Users.Find(userId);
    
    var isAvailable = _dbcontext.Entry(userEntity)
                            .Collection(e => e.Activities)
                            .Query().Any(e => e.Name== "givenname");
    

    时间:5.95秒 +获取用户的时间

    所以选择第二种形式的查询似乎是合理的。

3 个答案:

答案 0 :(得分:1)

我会将其简化为:

var userEntity = _dbcontext.Users.Find(userId);

var isAvailable = userEntity.Activities.Any(a => a.Name == "givenname");

或者也许(我不太清楚你要从你的问题中尝试实现什么) - 这并没有考虑到userId,它只是搜索< em> 任何活动的用户givenname

var isAvailable = _dbcontext.Users.Any(u => u.Activities.Any(a => a.Name == "givenname"));

答案 1 :(得分:1)

你也可以试试这个:

var isAvailable =_dbcontext.Users.Include(e => e.Activities)
                                 .Any( u => u.UserId == userId 
                                        &&  u.Activities.Any(a => a.Name == "givenname")
                                     );

如果您尚未停用延迟加载,则无需调用Include扩展方法。

答案 2 :(得分:0)

单程DB:

var result = _dbcontext.Users.Where( u => u.UserId == userId )
    .Select( u => new {
        User = u, // optional
        IsAvailable = u.Activities.Any( a => a.Name == "givenname" )
    } )
    .SingleOrDefault();