我正在尝试以流畅的方式使用automap功能来生成一个 DDL用于以下模型和程序,但不知怎的,我不断获取 我打电话时出现错误“关联引用未映射的类:IRole” NHibernate中的GenerateSchemaCreationScript方法。当我更换 具有接口实现的IList的类型(User 和角色)一切正常。我在这做错了什么?我怎么能够 使用已定义的IUser和IRole的已实现版本 在Unity?
public interface IRole
{
string Title { get; set; }
IList<IUser> Users { get; set; }
}
public interface IUser
{
string Email { get; set; }
IList<IRole> Roles { get; set; }
}
public class Role : IRole
{
public virtual string Title { get; set; }
public virtual IList<IUser> Users { get; set; }
}
public class User : IUser
{
public virtual string Email { get; set; }
public virtual IList<IRole> Roles { get; set; }
}
我使用以下程序生成DDL NHibernate中的GenerateSchemaCreationScript:
class Program
{
static void Main(string[] args)
{
var ddl = new NHibernateSessionManager();
ddl.BuildConfiguration();
}
}
public class NHibernateSessionManager
{
private ISessionFactory _sessionFactory;
private static IUnityContainer _container;
private static void InitContainer()
{
_container = new UnityContainer();
_container.RegisterType(typeof(IUser), typeof(User));
_container.RegisterType(typeof(IRole), typeof(Role));
}
public ISessionFactory BuildConfiguration()
{
InitContainer();
return
Fluently.Configure().Database(MsSqlConfiguration.MsSql2008
.ConnectionString("ConnectionString"))
.Mappings(m => m.AutoMappings.Add(
AutoMap.AssemblyOf<IUser>()))
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
}
private void BuildSchema(Configuration cfg)
{
var ddl = cfg.GenerateSchemaCreationScript(new
NHibernate.Dialect.MsSql2008Dialect());
System.IO.File.WriteAllLines("Filename", ddl);
}
}
答案 0 :(得分:1)
我和你的情况相同。在我知道你可以使用Fluent之前使用了ClassMap,但之前从未使用过AutoMapping功能。我已经成功地使用IReferenceConvention与AutoMapper进行一对一映射(参见之前的SO post)。
我现在遇到了和你一样的问题,我有一对多的映射,我现在遇到了问题。有一个IHasManyConvention接口,我已经开始看,但到目前为止还没有运气。
仅仅因为有些事情很难做到它并没有错,映射到接口具有价值,可以在原始的nHibernate映射文件中或使用Fluents ClassMap映射文件轻松完成。我认为一旦人们开始使用AutoMapping功能做更多的事情,就会有更多的博客帖子。
修改强>
我找到了使用IAutoMappingOverride的临时解决方案。以下是您需要的粗略示例。
public class RoleAutoMappingOverride : IAutoMappingOverride<Role>
{
public void Override(AutoMapping<Role> mapping)
{
mapping.HasMany<User>( x => x.Users ).KeyColumn( "User_id" );
}
}
修改强>
我的一所大学已经找到了一个更好的解决方案,它使用约定而不是覆盖。这包括如何进行单个课程,但如果你看一下我之前提到的SO帖子,你就可以看到它如何成为通用的。
public class Foo : IHasManyConvention
{
public void Apply(IOneToManyCollectionInstance instance)
{
if (instance.ChildType == typeof(Role))
{
instance.Relationship.CustomClass<User>();
}
}
}
修改强>
我现在把这个和我的另一篇文章转到博文中: http://bronumski.blogspot.com/2011/01/making-fluent-nhibernate-automapper.html
答案 1 :(得分:0)
您无法在AssemblyOf<T>
中提供类型为T的接口,您需要提供具体类型。或者您可以使用接受assebles的方法:
.Mappings(m => m.AutoMappings.Add(
AutoMap.Assembly(myAssembly)))
编辑:问题是您的类包含接口类型的集合而不是类类型。我不知道是否有可能以这种方式自动化接口。另外,我认为使用接口来指定域对象很少有任何价值。