如何使用NHibernate从其他数据源映射和引用实体

如何使用NHibernate从其他数据源映射和引用实体,nhibernate,nhibernate-mapping,Nhibernate,Nhibernate Mapping,我目前正在开发ASP.NET MVC应用程序,其中我有一个用户实体,如下所示: public class User { public virtual int Id { get; protected set; } public virtual string Name { get; protected set; } public virtual string Role { get; protected set; } public virtual Location Lo

我目前正在开发ASP.NET MVC应用程序,其中我有一个
用户
实体,如下所示:

public class User
{
    public virtual int Id { get; protected set; }
    public virtual string Name { get; protected set; }
    public virtual string Role { get; protected set; }
    public virtual Location Location { get; protected set; }
}
位置也同样简单:

public class Location
{
    public virtual string Id { get; protected set; }
    public virtual string Building { get; protected set; }
    public virtual string City { get; protected set; }
    public virtual string Region { get; protected set; }
}
我的复杂性是因为我想从Active Directory而不是数据库填充
用户
。此外,几个持久化到数据库的类将用户作为属性引用。我有一个用于检索的
ADUserRepository
,但我不知道如何将这些用户集成到我的对象图中,而其余的由NHibernate管理

NHibernate是否有一种方法可以只为
用户
保留一个id,而不将其作为用户表的外键?我可以把它映射为一个组件来完成这项工作吗?我还研究了实现
IUserType
来进行翻译。这样,它将映射到一个简单的字段,
ADUserRepository
可以放入链中以解析存储的Id。或者我正在尝试破解一些不太可行的东西?这是我第一次与NHibernate合作,因此我非常感谢您提供的任何见解或解决方案。谢谢

更新


在这方面,我的最佳解决方案似乎是使用IUserType映射用户,并在返回对象之前注入(最好是使用StructureMap)一个用于填充对象的服务。从这个角度来看,这里有几个问题涉及这个主题,主要是建议需要一个自定义字节码提供程序。我是否仍需要这样做才能让IUserType接受参数化构造函数,或者在此处进行注释:与众不同?

使用Usertype将用户转换为id并返回

public class SomeClass
{
    public virtual string Id { get; protected set; }
    public virtual User User { get; protected set; }
}

// in FluentMapping (you have to translate if you want to use mapping by code)

public SomeClassMap()
{
    Map(x => x.User).Column("user_id").CustomType<UserType>();
}

public class UserType : IUserType
{
    void NullSafeSet(...)
    {
        NHibernateUtil.Int32.NullSafeSet(cmd, ((User)value).Id, index);
    }
    void NullSafeGet(...)
    {
        int id = (int)NHibernateUtil.Int32.NullSafeGet(cmd, ((User)value).Id, index);
        var userrepository = GetItFromSomeWhere();
        return userrepository.FindById(id);
    }
}
公共类SomeClass
{
公共虚拟字符串Id{get;protected set;}
公共虚拟用户用户{get;protected set;}
}
//在FluentMapping中(如果要使用代码映射,则必须进行转换)
公共类映射()
{
Map(x=>x.User).Column(“User_id”).CustomType();
}
公共类用户类型:IUserType
{
无效NullSafeSet(…)
{
NHibernateUtil.Int32.NullSafeSet(cmd,((用户)值).Id,索引);
}
void NullSafeGet(…)
{
intid=(int)NHibernateUtil.Int32.NullSafeGet(cmd,((用户)值).id,索引);
var userrepository=getitfromwhere();
返回userrepository.FindById(id);
}
}

如果用户实体有一个对应的表,其中包含从active directory中提取的某些属性(即未映射)的信息,那么通过NHibernate的EventListeners框架{Ns:NHibernate.Event}或IInterceptor{Ns:NHibernate}就完全可能实现。到目前为止,用户没有自己的表。我确实尝试过这种方法,实现了一个PostLoadEventListener,但它需要为每个引用用户的对象提供逻辑。我宁愿隐藏用户是如何从这些实体返回的。如果您使用接口以用户作为成员来标识实体,则无需这样做。IUserType绝对是一个选项,我对它的疑虑一直是hbm中需要的明确规范(不太精通fluent,所以对此一无所知),我想每个人都有自己的缺点!