linq:聚合成单行(展平)

时间:2018-02-10 23:19:19

标签: c# linq entity-framework-core flatten

我目前正在使用linq并使用for循环访问一些元数据:

public SignUpMeta GetSignUpMeta(User user)
{
    var users = (from u in User
                where user.Email == u.Email || user.UserName == u.UserName
                select u);
    var result = new SignUpMeta();
    foreach (var u in users)
    {
        if (user.Email == u.Email) result.IsDuplicateEmail = true;
        if (user.UserName == u.UserName) result.IsDuplicateUserName = true;
    }
    return result;
}

Linq有没有办法直接生成SignUpMeta? 这个函数在DBContext类中,我正在寻找一种直接从db获取精确数据的方法(没有原始sql)。

更新 UserDbSet,整个代码在db上下文类中运行。我正在尝试编写一些能够使EF直接在单个查询中获取值的内容。

更新2: 我正在寻找的SQL等价物是:

SELECT MAX(username), MAX(email)
(SELECT CAST((UserName = @user) AS bit) username, 
        CAST((Email = @email) AS bit) email
 FROM User WHERE UserName = @user OR Email = @email)

更新3: 需要获取的SignUpMeta对象包含提供服务器端验证所需信息的元数据。

上面的C#代码运行一个查询,在这个实例中最多可以获取两列。当有更多这样的条件时,会有更多的线条。我试图找到一种方法,EF只能在一个记录中单独给出两个布尔值。

2 个答案:

答案 0 :(得分:0)

如果你真的必须使用LINQ:

,这将是我的尝试
from u in stuff.Users
group u by 0 into grp
select new
{
    IsDuplicateEmail = grp.Any(x => x.Email == user.Email),
    IsDuplicateUserName = grp.Any(x => x.UserName == user.UserName)
}

实体框架会将其转换为子选择。如果您正在使用SQL Server并且两列都已建立索引,那么这将导致与示例SQL相同的I / O数量。

我不相信有任何查询可以生成所需的示例SQL。

答案 1 :(得分:-2)

我认为这将是最快的查询:

public SignUpMeta GetSignUpMeta(User user)
{
    return new SignUpMeta()
    {
        IsDuplicateEmail = User.Where(u => u.Email == user.Email).Take(1).Any(),
        IsDuplicateUserName = User.Where(u => u.UserName == user.UserName).Take(1).Any(),
    };
}

数据库服务器上的缓存应该使这两个查询非常快。