我正在尝试让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下工作了几个月。
答案 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");
}
}