如何使用Fluent NHibernate映射部分aspnet_Users表

时间:2010-01-26 18:57:16

标签: fluent-nhibernate asp.net-membership automapping

我正在尝试让Fluent NHibernate 1.0 RTM为我映射一个User实体,这样我就可以通过NHibernate访问我的ASP.NET MVC应用程序中的UserId和UserName。

我有:

public class User
{
    public virtual Guid UserId { get; protected set; }
    public virtual string UserName { get; protected set; }
}

它表示只包含要映射的相关列的aspnet_Users表。这是唯一没有自动化的实体。这是我的映射:

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        Id(x => x.UserId);
        Map(x => x.UserName);
        WithTable("aspnet_Users");
    }
}

其他所有内容都通过惯例自动化。

以下是我的PrimaryKeyConvention和TableNameConvention:

public class PrimaryKeyConvention : IIdConvention
{
    public void Apply(IIdentityInstance instance)
    {
        instance.Column(instance.Property.ReflectedType.Name + "Id");
        instance.UnsavedValue(System.Guid.Empty.ToString());
        instance.GeneratedBy.GuidComb();
    }
}

public class TableNameConvention : IClassConvention
{
    public void Apply(IClassInstance instance)
    {
        instance.Table(Inflector.Net.Inflector.Pluralize(instance.EntityType.Name));
    }
}

映射过程在执行ClassMap代码(在所有自动化之前)之后立即失败,然后是TableNameConvention代码,然后是PrimaryKeyConvention代码。失败在PrimaryKeyConvention中,因为instance.Property为null。我试着做一个if(instance.Property!= null)但是那个 使用“缺少必需属性'类'错误”错误地提前终止映射过程。我在TableNameConvention中也有一个if(instance.EntityType!= typeof(User)),但是当它没有区别时就取出了。

这里发生了什么?首先,为什么AutoMapping进程调用ClassMap的约定?其次,为什么PrimaryKenConvention会传递一个instance.Property == null?如何使这个工作正常运行,以便映射过程继续运行并使用AutoMapping +约定映射其余实体?

请注意,在1.0 RTM的重构之前,我已经在早期版本的FNH下工作了几个月。

2 个答案:

答案 0 :(得分:1)

我已经找到了答案。

public UserMap()
{
    Id(x => x.UserId);
    Map(x => x.UserName);
    Table("aspnet_Users");
}

public class PrimaryKeyConvention : IIdConvention
{
    public void Apply(IIdentityInstance instance)
    {
        instance.Column(instance.EntityType.Name + "Id");
        instance.UnsavedValue(System.Guid.Empty.ToString());
        instance.GeneratedBy.GuidComb();
    }
}

public class TableNameConvention : IClassConvention
{
    public void Apply(IClassInstance instance)
    {
        instance.Table(Inflector.Net.Inflector.Pluralize(instance.EntityType.Name));
    }
}

请注意,PrimaryKeyConvention使用instance.EntityName而不是instance.Property设置列名。对于UserMap,后者为null,因此会崩溃。

这种方法比在(null!= instance.Property)上使用条件语句并保留instance.Property.ReflectedType.Name行更好,但两者都有效。如果选择转到该路径,则必须在UserMap中显式设置列名:

public UserMap()
{
    Id(x => x.UserId).Column("UserId")
                     .GeneratedBy.Assigned();
    Map(x => x.UserName).Column("UserName");
    Table("aspnet_Users");
}

答案 1 :(得分:0)

我自己不使用自动映射,但我认为您需要通过实施IAutoMappingOverride来映射用户。类似的东西:

public class UserMap : IAutoMappingOverride<User>
{
    public void Override(AutoMapping<User> mapping)
    {
        mapping.Id(x => x.UserId);
        mapping.Map(x => x.UserName);
        mapping.WithTable("aspnet_Users");
    }
}