【问题标题】:How to use Immutable Objects with SQLite?如何在 SQLite 中使用不可变对象?
【发布时间】:2021-02-23 21:03:56
【问题描述】:

尝试初始化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
}

【问题讨论】:

    标签: c# .net sqlite sqlite-net sqlite-net-pcl


    【解决方案1】:

    说明

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

    回答

    我们可以利用Init-Only Setters,C# 9.0 中的新功能。

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

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

    代码

    移除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
    }
    

    【讨论】:

      【解决方案2】:

      另一种选择是创建一个 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;
      }
      

      【讨论】:

        猜你喜欢
        • 2014-08-24
        • 1970-01-01
        • 2011-07-02
        • 2014-09-03
        • 2021-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多