带有FluentNHibernate的引用上的CustomType

时间:2019-02-18 12:35:18

标签: c# nhibernate fluent-nhibernate language-ext

我正在使用一个名为LanguageExt的库。该库提供了一些工具来处理C#代码中的功能编程。我还使用FluentNHibernate来将域类映射到数据库。

当属性为空时,我想使用LanguageExt中的Option<T>。这是一个保留值或等于None的结构。

我的一个类模型,例如Car具有一个可选属性,例如Sunroof,其类型为Option<Window>。像这样:

public class Car
{
   Window _sunroof;
   Option<Window> Sunroof
   {
     get => Optional(_sunroof);
     set => _sunroof = value.IfNoneUnsafe(() => null);
   }
}

我的映射是这样的:

References<Window>(x => x.Sunroof, "idSunroof")
   .Not.Nullable();

我的问题是:知道它们不具有相同的返回类型时,如何使用其后备字段映射天窗属性?

2 个答案:

答案 0 :(得分:3)

  

这是一个域模型,但也通过FluentNHibernate完成的映射配置映射到数据库中的某个表。

我认为这不是一个好主意。您正在尝试在这一课中做三(或四)件事,我会分开做。

我建议拥有NHibernate的DTO(可能称为CarDto)和业务模型(可能称为Car)。这样,CarDto可以由于与数据库相关的原因而改变(但不是出于建模原因),而Car可以由于建模的原因而改变(但不是由于数据库原因)。例如,函数式编程将使业务模型不可变,但是NHibernate可能要求其DTO是可变的。如果您同时使用相同的类型,那么就不能满足所有的设计约束。

  

在知道它们不具有相同的返回类型的情况下,如何使用其后备字段映射天窗属性?

我不认为您应该具有不同类型的属性和支持字段。对于CarDto,使用null表示没有Window。然后,从CarDto映射到Car时,将null映射到None状态(通过当前使用的Optional函数)。然后,当从Car映射到CarDto时,将None映射回null(通过当前使用的IfNoneUnsafe方法)。

您的Car

  1. 是NHibernate的DTO,
  2. 是您的业务模式,
  3. 包含从DTO到业务模型的映射,并且
  4. 包含从业务模型到DTO的映射。

这是我上面提到的三到四件事(取决于您将映射算作一件事还是两件事)。

添加了2019-02-20

  

[您的答案不是]解决我的问题的方法,而是提出一个更好的体系结构的建议

都是。

  

我完全同意您的意见,我很乐意这样做,但我不能。在我的代码库中,我有250多个模型类,它们设计得很差,并且存在很多错误创建的依赖项。我不能一次重构所有这些。

我不建议您立即更改所有内容。离得很远。按照马丁·福勒(Martin Fowler)的Refactoring的风格,我建议您随时间进行许多小的更改。

例如,将Car更改为

有多困难
public class Car
{
   Option<Window> Sunroof
   {
     get => Optional(SunroofBacking);
     set => SunroofBacking = value.IfNoneUnsafe((Window) null);
   }
   Window SunroofBacking { get; set; }
}

并出于业务逻辑原因而使用(命名为“更好”的)属性Sunroof,而出于SunroofBacking原因而使用NHibernate

答案 1 :(得分:0)

我终于找到了解决方法:

References(x => x.Sunroof, "idSunroof")
    .Access.CamelCaseField(Prefix.Underscore)
    .Class<Window>();