ORM与实体类和域接口/类

时间:2011-05-23 20:02:53

标签: orm architecture interface dns

我正在尝试决定如何处理与通过ORM填充的对象的域级类和接口(在本例中为NHibernate)。我嘲笑了一个非常简单的场景,有助于说明我目前的情况。

public interface ICar
{
    public bool PassesEmisionStandards(string state);
    public int Horsepower { get; set; }
    public string Model { get; set; }
}

public class CarFromDB
{
    public int Horsepower { get; set; }
    public string Model { get; set; }
}

public class ModelT : CarFromDB, ICar
{
    public bool PassesEmissionStandards(string state)
    {
        return false;
    }

    public override string ToString()
    {
        return Model + " with " + Horsepower + " ponies";
    }
}

在这种情况下,CarFromDB是通过NHibernate映射到我的数据库的类。 ICar是我的UI / Controller代码正在处理的接口。 ModelT是将实例传递给UI的类之一。

在我的实际域中,PassesEmissionStandards是一个复杂的方法,它在不同的派生类之间有很大的不同,而CarFromDB类有十几个简单属性以及对其他类的引用,包括单个和列表。此信息全部用于PassesEmissionStandards等效项。

当我从ORM中使用填充的基类开始时,我对使用界面修饰的派生类的最佳方法感到困惑。我试图解决这个问题的想法是:

  1. 使用ICar装饰CarFromDB并尝试用一种干净的方式在其中实现广泛的PassesEmissionStandards方法,或者通过呼叫其他类来寻求帮助
  2. 使用AutoMapper或等效的+工厂将我的基类对象转换为派生类对象
  3. 由于可以从基类中的属性中识别派生类类型,因此可以使用NHibernate的派生类,并找到一些方法来挂钩NHibernate,以指示它使用哪个映射派生类。
  4. 我觉得这一定是一个非常普遍的问题,但我在SO和其他地方搜索过而没有找到任何可靠的指导方针。请注意:我对ORM和域建模相对较新,对NHibernate也很新。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

我不认为我理解你的问题,你为什么不能使用:

public interface ICar
{
    public bool PassesEmisionStandards(string state);
    public int Horsepower { get; set; }
    public string Model { get; set; }
}

public abstract class CarBase : ICar
{
    public int Horsepower { get; set; }
    public string Model { get; set; }
    public abstract bool PassesEmisionStandards(string state);
}

或者如果CarBase也用于所有派生类,您可能想要使用策略模式

public interface IEmissionCalculator
{
    void Calculate(IEmissionCalculatorContext context);
}

public CarBase : ICar
{
    internal void Assign(IEmissionCalculator calculator){}

    public bool PassesEmisionStandards(string state)
    {
        //assign all info needed for calculations
        var ctx = new IEmissionCalculatorContext {  };
        return _calculator.Check(ctx);
    }
}

您可以使用相同的DB级别,但根据汽车类型分配不同的排放量。

如果这也不起作用,我会使用automapper。