c# - C# & Entity Framework linq 查询如何在对象为空时返回映射器

我有以下查询。当数据库中没有匹配的记录时,该方法返回null。但我希望响应返回具有空属性的对象。如何做到这一点?

public async Task<UserResponse> GetUserByEmployeeId(string employeeNumber)
    {
        var userRecord = await _context.User
            .AsNoTracking()
            .Include(u => u.Manager)
            .Where(x => x.PersonNumber == employeeNumber)
            .Select(user => UserReponseMapper.ToUserResponse(user))
            .FirstOrDefaultAsync();

        // The following returns expected value: 
        // But, looking for a better solution
        
        /*
        if(userRecord == null)
        {
            userRecord = new UserResponse();
        }
        */

        return userRecord;
    }
    
    public static UserResponse ToUserResponse(User user)
    {
        return new UserResponse
        {
            EmployeeNumber = user.PersonNumber,
            ManagerNumber = user.Manager?.PersonNumber
        };
    }

没有匹配记录时的预期结果

{
  EmployeeNumber: null,
  ManagerNumber: null
}

目前得到的结果为 NULL;

回答1

如果没有匹配的记录,则不调用 ToUserResponse 并且 FirstOrDefaultAsync 返回 null。您可以使用 https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-coalescing-operator 来返回替代方案:

public async Task<UserResponse> GetUserByEmployeeId(string employeeNumber)
{
    var userRecord = (await _context.User
        .AsNoTracking()
        .Include(u => u.Manager)
        .Where(x => x.PersonNumber == employeeNumber)
        .Select(user => UserReponseMapper.ToUserResponse(user))
        .FirstOrDefaultAsync()) 
        ?? new UserResponse() { EmployeeNumber: null, ManagerNumber: null };
    // ...

该运算符检查第一个参数的结果是否为空;如果结果不为null,则返回,否则返回第二个参数。它基本上是示例中 if 语句的简短形式。

回答2

如果你想压缩线条。

userRecord = (userRecord == null) ? new UserResponse() : userRecord;

或者,如果您想将其添加到原件中,您可以添加 Elvis 运算符。 “??”

var userRecord = (await _context.User
    .AsNoTracking()
    .Include(u => u.Manager)
    .Where(x => x.PersonNumber == employeeNumber)
    .Select(user => UserReponseMapper.ToUserResponse(user))
    .FirstOrDefaultAsync()) 
    ?? new UserResponse();
 // ^ Checks for null

如果 user 也为空,您需要更改您的构造。

return new UserResponse
    {
        EmployeeNumber = user?.PersonNumber,
        ManagerNumber = user?.Manager?.PersonNumber
    };

回答3

我的评论错了(并删除了它),但它让我思考;因为您可能想向“当结果为空时创建这个新对象”添加更多逻辑,所以您可以执行以下“伪代码”之类的操作(它可以编译,但它只是测试代码)

public async Task<ResultObject> GetResultObjectAsync()
    {
        return ProcessResult(
             (await GetResult())
            .Where(x => x?.ID == new Guid())
            .FirstOrDefault());
    }

    // this is your DB
    async Task<List<ResultObject>> GetResult()
    {
        return new List<ResultObject>();
    }

    // this is the null-coalesce replacement
    public static ResultObject ProcessResult(ResultObject? value)
    {
        if (value == null) return new ResultObject(); // or add more info like setting default values
        return value;
    }

    // this is just a simple POCO for testing
    public class ResultObject
    {
        public Guid ID { get; set; }
    }

相似文章