使用 EF CORE 检索可为 null 的对象

Retrieve nullable object using EF CORE

我是初学者,在测试一些代码时,我似乎无法理解如何正确执行此操作..

第一个:我有一个城市class:

public class City
{
    public City()
    {
        ZipCode = "";
        Name = "";
    }

    public int Id { get; set; }
    public string ZipCode { get; set; }
    public string Name { get; set; }
}

第二:我有一个联系人 class 使用可为空的城市 class(如果用户不知道城市):

public class Contact
{
    public Contact()
    {
        Name = "";
        Line1 = "";
        Line2 = "";
        CityId = null;
        City = new City();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public string Line1 { get; set; }
    public string Line2 { get; set; }

    private int? _CityId;
    public int? CityId
    {
        get { return _CityId; }
        set { _CityId = value < 1 ? null : value; }
    }

    private City _City;
    public City City
    {
        get { return _City; }
        set { _City = _CityId == null ? null : value; }
    }
}

我遇到的问题当我检索存储了空城市的记录时(检索记录并且它的城市不为空,一切都会正常)。我的 .Select() 语句如下所示:

var result = await _context.Contact
            .Where(w => w.Id == id)
            .Include(q => q.City)
            .Select(s => new Contact
            {
                // Entity
                Id = s.Id,
                // Model
                Line1 = s.Line1,
                Line2 = s.Line2,
                CityId = s.CityId,
                City = new City // I am retrieving this so that I can get the inner data as well
                {
                    // Entity
                    Id = s.City.Id,
                    // Model
                    ZipCode = s.City.ZipCode,
                    Name = s.City.Name,
                }
            }).FirstOrDefaultAsync();

对于没有空城市的记录,输出没有问题,但是如果用户检索到城市为空的记录,它会抛出以下错误

可为 Null 的对象必须有一个值。

任何人都可以教我如何正确地做到这一点吗?提前致谢!

您不需要使用 Select 创建新实体,您会收到错误消息,因为如果 s.City 为空 s.City.Id 不存在。 Insteat直接搜索它使用

var result = await _context.Contact
            .Include(q => q.City)
            .FirstOrDefaultAsync(x => x.Id == id);

为什么你使用 Select 并为 city 使用私有 属性?

联系Class:

public class Contact
{
    public Contact()
    {
        Name = "";
        Line1 = "";
        Line2 = "";
        CityId = null;
        City = new City();
    }

    public int Id { get; set; }
    public string Name { get; set; }
    public string Line1 { get; set; }
    public string Line2 { get; set; }

    public int? CityId;
    public City City
    
}

您的Select与实体class相同,不需要使用

var result = await _context.Contact
            .Include(q => q.City)
            .FirstOrDefaultAsync(f => f.Id == id);

感谢大家的解答!

我发现罪魁祸首是这行代码(感谢您的回答和解释):

Id = s.City.Id

那是因为Id这里是一个int不可为空,因为这是MSSQL中的一个Identity) 但当 CityId 以及城市对象)在数据库中存储一个 null 时, s.City.Id 也将在 .Select().

中包含 null

上述情况下的Id = s.City.Id失败,因为Id (not nullable) 被迫接收 null 包含在 s.City.Id 中)。