1

尝试初始化我的SQLite-NET数据库时,我不断收到以下错误:

无法创建没有列的表('PersonModel' 有公共属性吗?)

我有一个PersonModel我想要不可变的类,但是 SQLite 告诉我它PersonModel必须是可变的,例如每个属性都必须使用public set;.

如何继续使用具有不可变属性的 SQLite-NET ?

class Person
{
    public Person(string firstName, string lastName)
    {
        FirstName = firstName;
        LastName = lastName;
    }

    public string FirstName { get; } //Read-only Property, cannot be changed after initialization
    public string LastName { get; } //Read-only Property, cannot be changed after initialization
}
4

2 回答 2

3

解释

发生该错误是因为 SQLite-NET 使用反射来初始化它从我们的数据库中检索的对象,而反射需要public set;初始化每个属性。

回答

我们可以利用C# 9.0中新增的Init-Only Setters

Init-Only Setter 允许我们定义可以在初始化期间设置的属性,并且不能更改。换句话说,init-only setter 让我们创建不可变对象,并且它们允许反射创建不可变对象!

我在这篇博文中深入探讨了这个主题:https ://codetraveler.io/2020/11/11/using-immutable-objects-with-sqlite-net/

代码

移除 on 的构造函数Person(反射需要一个无参数的构造函数),并为每个属性实现仅初始化设置器:

class Person
{
    public string FirstName { get; init; } //Read-only Property, can be set during initialization, but cannot be changed after initialization
    public string LastName { get; init; } //Read-only Property, can be set during initialization, but cannot be changed after initialization
}
于 2020-11-11T21:03:49.243 回答
0

另一种选择是创建一个PersonDto执行所有 SQLite 交互的类:

class PersonDto
{
    
    public PersonDto(string firstName, string lastName)
    {
        this.FirstName = firstName;
        this.LastName = lastName;
    }

    public string FirstName { get; set; }
    public string LastName { get; set; }
}

然后Person该类封装了 DTO 对象:

class Person
{
    private PersonDto _dto;
    
    public Person(PersonDto dto)
    {
        this._dto = dto;
    }

    public string FirstName => _dto.FirstName;
    public string LastName => _dto.LastName;
}
于 2020-11-11T21:11:59.297 回答