POCO,ORM和不变性。如何使他们一起工作?

Sar*_*kar 4 c# orm immutability poco

假设我有一个下面的C#类,我希望它是不可变的。您只能使用参数化的构造函数进行设置。

public class InsulineInjection
{
    private InsulineInjection()
    {
        // We don't want to enable a default constructor.
    }

    public InsulineInjection(Millilitre millilitre, DateTime dateTime, string remark)
    {
        this.Remark = remark;
        this.DateTime = dateTime;
        this.Millilitre = millilitre;
    }

    public string Remark { get; private set; }
    public DateTime DateTime { get; private set; }
    public Millilitre Millilitre { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)

现在,我想使用一个ORM创建此POCO。但是,据我所知,所有.NET ORM都希望可以访问属性并具有一个公共构造函数来创建此POCO。因此,我必须将POCO更改为:

public class InsulineInjection
{
    public InsulineInjection()
    {
    }

    public InsulineInjection(Millilitre millilitre, DateTime dateTime, string remark)
    {
        this.Remark = remark;
        this.DateTime = dateTime;
        this.Millilitre = millilitre;
    }

    public string Remark { get; set; }
    public DateTime DateTime { get; set; }
    public Millilitre Millilitre { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

但是,这使我的POCO再次可变。有人使用它之后可以简单地更改我不想要的任何属性。

据我所知,我可以通过两种不同的方式解决此问题:

  1. 编写我自己的数据访问层(或修改orm),以便能够使用我创建的构造函数创建正确的POCO实例。
  2. 创建某种映射器。让ORM创建简单的DTO对象,并在适当的时候使用映射器将DTO对象转换为我的POCO。

我倾向于解决方案2。有人对此有示例吗?还是有比我上面描述的解决方案更好的解决方案?

jga*_*fin 5

只要有默认的构造函数和设置器,许多OR / M都可以工作(无论它们是否公开,它们都必须存在)

所以这行不通(没有默认构造函数):

public class InsulineInjection
{
    public InsulineInjection(Millilitre millilitre, DateTime dateTime, string remark)
    {
        this.Remark = remark;
        this.DateTime = dateTime;
        _millilitre = millilitre;
    }

    public string Remark { get; set; }
    public DateTime DateTime { get; set; }
    public Millilitre Millilitre { get { return _millilitre; } }
}
Run Code Online (Sandbox Code Playgroud)

或这个(最后一个属性没有设置器)

public class InsulineInjection
{
    public InsulineInjection(Millilitre millilitre, DateTime dateTime, string remark)
    {
        this.Remark = remark;
        this.DateTime = dateTime;
        _millilitre = millilitre;
    }

    public string Remark { get; set; }
    public DateTime DateTime { get; set; }
    public Millilitre Millilitre { get { return _millilitre; } }
}
Run Code Online (Sandbox Code Playgroud)

尽管这将起作用:

public class InsulineInjection
{
    protected InsulineInjection()
    {
        // works with many OR/Ms
    }

    public InsulineInjection(Millilitre millilitre, DateTime dateTime, string remark)
    {
        this.Remark = remark;
        this.DateTime = dateTime;
        this.Millilitre = millilitre;
    }

    public string Remark { get; private set; }
    public DateTime DateTime { get; private set; }
    public Millilitre Millilitre { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)