使用NHibernate 4映射byte []会从.net中引发数组异常

时间:2015-06-22 03:26:07

标签: c# arrays nhibernate fluent-nhibernate

我使用当前的4.0.3版来映射一些MySQL表。但是,我已经遇到了使用自动播放器创建映射的问题!原因:一个字节数组!只要我添加一个字节数组,如" byte()" (vb.net语法)我得到一个例外:

"无法重新获取阵列上通用接口的接口映射。"

似乎这个异常来自.NET我认为更深入但事情是:我没有Fluent nhibernate映射的这个问题! Fluent将我的字节数组映射到一个longblob,这是我期望的。但是,NHibernate 4没有。不幸的是,当Fluent包含一些描述(例如" EmployeeId")时,Fluent并不聪明地映射我的Id-Properties。我需要将我的所有属性重命名为" Id"避免手动映射。因此,我想使用NHibernates automapper而不是它似乎无法处理任何类型的数组(我也尝试使用整数数组,同样的例外)。有没有人有同样的问题?这是我的代码:

Public Cfg As Configuration
Public Mapping As HbmMapping
Public SessionFactory As ISessionFactory

Public Sub New()
        CreateConfig()
        Map()
        SessionFactory = Cfg.BuildSessionFactory()
End Sub

Public Sub CreateConfig()
        Cfg = New Configuration()
        Cfg.DataBaseIntegration(AddressOf DbIntegration)
End Sub

Private Shared Sub DbIntegration(c As IDbIntegrationConfigurationProperties)
        c.ConnectionString = "Server=xxx;Port=3306;Database=xxx;User ID=xxx;Password=xxx;"
        c.Driver(Of MySqlDataDriver)()
        c.Dialect(Of MySQL55Dialect)()
        c.LogSqlInConsole = True
        c.LogFormattedSql = True
        c.AutoCommentSql = True
    End Sub

Public Sub Map()
        Dim automapper As New ConventionModelMapper()
        Mapping = automapper.CompileMappingFor(Assembly.GetExecutingAssembly().GetExportedTypes().Where(Function(x) x.[Namespace].StartsWith("xxx.Models")))
        Cfg.AddMapping(Mapping)
    End Sub

除了包含数组的实体外,所有这些对我的所有实体都有效。实际上我需要使用的唯一数组是使用字节数组的单个实体中的字节数组。我尝试使用BeforeMapProperty事件覆盖映射,但无论如何抛出异常,因为我认为错误发生在该事件之前。

谢谢! 最好, 克里斯

1 个答案:

答案 0 :(得分:1)

ConventionModelMapper正在评估byte[]以尝试确定实体→byte是一对多关系时,就会发生这种情况。 NHibernate看到了一个集合,并尝试将其作为一对多关系进行处理。

显然这不是真的,因为byte显然不是自定义类型。但在大多数情况下,NHibernate评估这种关系是有意义的,试图弄清楚"很多"一方是可能的一对多关系。

解决此问题的方法是创建自己的模型映射器(继承自ModelMapperConventionModleMapper)并定义"实体"在您的申请中。此检查将排除byte类型,错误应该消失。

幸运的是,这很简单:

public class MyModelMapper : ConventionModelMapper
{
    public MyModelMapper()
    {
        this.IsEntity((type, isDeclared) =>
        {
            return type.Namespace.StartsWith("Models");
        });
    }
}

然后使用MyModelMapper代替。

在我的(有限的)自动化体验中,您很可能必须覆盖常规模型映射器的大部分行为。幸运的是,通过一些试验和错误,这不是太难。