Fluent NHibernate - 将实体映射为不同类型

发布于 2024-09-17 23:02:32 字数 951 浏览 5 评论 0原文

我有一个类,我想将其作为组件映射到包含它的任何表上:

public class Time
{
    public int Hours { get; set; }
    public int Minutes { get; set; }
    public int Seconds { get; set; }
}

我想将此类作为 bigint 存储在数据库中 - 与 TimeSpan< 的方式相同/code> 已存储,但我的类具有完全不同的行为,因此我决定创建自己的类。

我正在使用 FLH 的自动映射器,并将此类设置为组件(其他类将 Time 作为属性)。我已经创建了一个覆盖,但不确定如何映射它:

我以这种方式尝试过:

public class TimeMappingOverride : IAutoMappingOverride<Time>
{
    public void Override(AutoMapping<Time> mapping)
    {
        mapping.Map(x => x.ToTimeSpan());
        mapping.IgnoreProperty(x => x.Hours);
        mapping.IgnoreProperty(x => x.Minutes);
        mapping.IgnoreProperty(x => x.Seconds);
    }
}

但得到了这个错误:

无法将“System.Linq.Expressions.UnaryExpression”类型的对象转换为“System.Linq.Expressions.MethodCallExpression”类型。

我该怎么办?

I have a class which I would like to map as a component onto any table which contains it:

public class Time
{
    public int Hours { get; set; }
    public int Minutes { get; set; }
    public int Seconds { get; set; }
}

I would like to store this class as a bigint in the database - the same as how TimeSpan is stored but my class has completely different behaviour so I decided to create my own.

I'm using FLH's automapper and have this class set as a component (other classes have Time as a property). I've got as far as creating an override but am not sure how to go about mapping it:

I gave it a try this way:

public class TimeMappingOverride : IAutoMappingOverride<Time>
{
    public void Override(AutoMapping<Time> mapping)
    {
        mapping.Map(x => x.ToTimeSpan());
        mapping.IgnoreProperty(x => x.Hours);
        mapping.IgnoreProperty(x => x.Minutes);
        mapping.IgnoreProperty(x => x.Seconds);
    }
}

But got this error:

Unable to cast object of type 'System.Linq.Expressions.UnaryExpression' to type 'System.Linq.Expressions.MethodCallExpression'.

How should I go about this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

暖风昔人 2024-09-24 23:02:32

组件的详细信息可以在这里找到:http://wiki. Fluentnhibernate.org/Fluent_mapping#Components

但首先,你不能映射方法。

假设您将 ToTimeSpan() 更改为属性 AsTimeSpan,有两种方法可以实现,只有其中较难的一种才适合您,因为您正在使用自动映射

  1. ComponentMap——完成后,您现有的映射将正常工作。这与自动映射不兼容。
  2. 声明内联组件映射:
mapping.Component(x => x.AsTimeSpan, component => {  
    组件.Map(小时);  
    组件.Map(分钟);  
    组件.Map(秒);  
    });

不过,你每次都必须这样做。

当然,这并没有解决“我想将此类存储为 bigint...”

您是说您只想将其保留为秒吗?如果是这样,请从头开始,您再次有两个选择:

  1. 实现 NHibernate IUserType (呃)
  2. 创建一个私有属性或字段,仅将值存储为秒,然后仅将其连接到 NHibernate。公共属性的 getter 和 setter 必须在秒之间进行转换。

Details of components can be found here: http://wiki.fluentnhibernate.org/Fluent_mapping#Components

But first of all, you can't map a method.

Assuming you change ToTimeSpan() to a property AsTimeSpan, there are two ways to do it, only the harder of which will work for you because you are using automapping:

  1. Create a ComponentMap<Time> -- once done, your existing mapping will just work. This is not compatible with automapping.
  2. Declare the component mapping inline:
mapping.Component(x => x.AsTimeSpan, component => {  
    component.Map(Hours);  
    component.Map(Minutes);  
    component.Map(Seconds);  
    });

You'll have to do this every time, though.

Of course, this doesn't address "I would like to store this class as bigint…"

Are you saying you want to persist it as seconds only? If so, scratch everything at the top and again you have two options:

  1. Implement NHibernate IUserType (ugh)
  2. Create a private property or field that stores the value as seconds only, and wire only this up to NHibernate. The getters and setters of the pubic properties will have to convert to/from seconds.
寂寞花火° 2024-09-24 23:02:32

我个人还没有使用过 AutoMappings,但我的建议是研究 NHibernate 的 IUserType 来更改类型的持久化方式。我相信这是定义 Time <-> 的自定义映射的更清晰的方法。 bigint

阅读上面的代码,Map(x => x.ToTimeSpan()) 将不起作用,因为您无法将应用程序到数据库的转换代码嵌入到映射中。即使这是可能的,该声明也错过了从数据库到应用程序的转换。另一方面,IUserType 可以在 NullSafeGetNullSafeSet 方法中执行自定义转换。

I personally haven't worked with AutoMappings yet, but my suggestion would be to look into NHibernate's IUserType to change how a type is being persisted. I believe that's a cleaner way of defining your custom mapping of Time <-> bigint.

Reading the code above, Map(x => x.ToTimeSpan()) will not work as you cannot embed application-to-database transformation code into your mappings. Even if that would be possible, the declaration misses the transformation from the database to the application. A IUserType, on the other hand, can do custom transformations in the NullSafeGet and NullSafeSet methods.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文