在执行时将Any()与IQueryable List一起使用会花费很长时间?

时间:2018-10-18 07:26:09

标签: c# linq

我有以下代码:

class FileOwners:

    @staticmethod

    def group_by_owners(files):
        new_dic = {}

        for key,val in files.items():
            key_list = []
            for k,v in files.items():

                if v == val:
                    #print(v)
                    key_list.append(k)
                    new_dic[v]= key_list

        return new_dic
        #print(new_dic)
files = {
    'Input.txt': 'Randy',
    'Code.py': 'Stan',
    'Output.txt': 'Randy'
}
print(FileOwners.group_by_owners(files))

List<int> projectIds=GetProjectsIds();// size is about 100,000 int value. List<int> userIds=GetUsersIds();// size is about 100,000 int value. List<int> nextIds=GetNextIds();// size is about 100,000 int value. var IQueryList= db.Users.Where(obj=> projectIds.any(x=>x==obj.ProjectID) || userIds.any(x=>x==obj.UserId) || nextIds.any(x=>x==obj.NextId) ); 转换为IQueryable时会花费很长时间。

List

如何解决此问题,还有其他方法可以应用于我的代码吗?

1 个答案:

答案 0 :(得分:2)

它称为Abstraction leak,是在 Linq-To-Entities (即实体框架)之间切换为- Linq-To-Objects 的结果。

基本法律规定,可靠软件的开发人员无论如何都必须学习抽象的基本细节。

含义

您的抽象公开了一些实现细节,但不幸的是您无法做任何事情。

来自wikipedia

  

泄漏抽象是指任何实现的抽象,旨在   减少(或隐藏)复杂性,其中底层细节不存在   完全隐藏

一种解决方法是创建具有良好约束的对象,并以尽可能少的条件维护linq查询。

在您的代码中,您使用的是WhereGroupBy,这可能会导致抽象泄漏的代价:

List<int> projectIds=GetProjectsIds();// size is about 100,000 int value.
List<int> userIds=GetUsersIds();// size is about 100,000 int value.
List<int> nextIds=GetNextIds();// size is about 100,000 int value.

//Linq to sql statement
var IQueryList= db.Users.Where(obj=> projectIds.Any(x=>x==obj.ProjectID) 
                                    || userIds.Any(x=>x==obj.UserId) 
                                    || nextIds.Any(x=>x==obj.NextId) );

//Linq to object, possible abstraction leak.
var YearsGroup = IQueryList.GroupBy(x => x.CreatedOn.Year)
                           .Select(g => g.FirstOrDefault())
                           .ToList()
                           .OrderByDescending(x => x.CreatedOn.Year);