有一个返回IEnumerable<User>
的方法,我一直在使用Linq / Entity Framework / SQL Server来返回结果。
我遇到了一个困难的条件scenario,这在C#迭代Web服务器上更容易解决(在linq语句链的末尾,就在将数据返回给客户端之前): / p>
public IEnumerable<User> ReturnUsersNotInRoles()
{
IQueryable<User> z = (from users
//...many joins..conditions...
).Distinct().Include(x => x.RoleUserLinks).ToList()
IEnumerable<User> list = new List<User>();
foreach (User user in z)
{
bool shouldReturnUser = true;
foreach (var rul in user.RoleUserLinks)
{
if (rul.LinkStatusID == (byte)Enums.LinkStatus.Added)
shouldReturnUser = false;
}
if (shouldReturnUser)
list.Add(user);
}
return list;
}
问题:在C#中,是否有更高性能/更少的内存开销方式?
我只会从Linq带回我需要的实体。没有N+1方案。目前表现非常出色。
我意识到理想情况下我会在SQL / Linq中编写它,因为SQL Server会发挥它的魔力并快速为我提供数据。但是,我正在通过潜在的v.hard查询来平衡这一点,以及当前迭代的优异性能,以及理解C#方式的简便性。
答案 0 :(得分:2)
这个怎么样:
public IEnumerable<User> ReturnUsersNotInRoles()
{
var z = (from users
//...many joins..conditions...
).Distinct().Include(x => x.RoleUserLinks);
var addedLinkStatusID = (int)Enums.LinkStatus.Added;
return z.Where(user =>
false == user.RoleUserLinks.Any(link => link.LinkStatusID == addedLinkStatusID))
.ToList();
}
这应该完全作为SQL查询运行 - 您可以通过在定义它的行的末尾添加z
来实现第一部分(.ToList()
)。
顺便说一下,关于你的问题“在C#中有更高性能/更少的内存开销方式吗?” - 首先,您可以在设置break
后立即添加shouldReturnUser = false;
语句。
其次,无论我是否使用数据库,我都更喜欢使用LINQ原语:
答案 1 :(得分:0)
你的循环等同于以下LINQ查询 - 我发现它比循环更容易理解,它允许在与查询的第一部分结合时在服务器上完全执行。
var linkStatusAdded = (Byte)Enums.LinkStatus.Added;
return z.Where(user => user.RoleUserLinks
.All(rul => rul.LinkStatusID != linkStatusAdded))
.ToList();