(流畅)NHibernate - 对象级别的继承,但不是表级别的继承

时间:2009-09-22 15:19:48

标签: nhibernate fluent-nhibernate nhibernate-mapping

我有以下想法:

业务对象实现为接口或抽象类,某些属性只读为除DAL层之外的所有层。我还希望我的业务对象在另一个程序集中而不是DAL(用于测试目的),因此标记属性对我来说不是一个选项。

示例可以是一对一关系或其他属性。

我几乎通过以下方式解决了这个问题

abstract class User
{
    public virtual long UserId {get; protected set;}
    public virtual string Password {get; protected set;}
    ...
}

在DAL中:

public class DbUser : User
{
    internal virtual void SetPassword(string password) {...}
}

然后我使用流利的方式将其映射为

ClassMap<User> {...}
SubclassMap<DbUser> {...}

我得到的问题是fluent尝试创建一个名为DbUser的表。

如果我跳过SubclassMap并创建一个DbUser对象并尝试保存它,我会得到一个“没有这个对象的持久性”错误。

有可能解决吗?

1 个答案:

答案 0 :(得分:0)

您可以覆盖使用Fluent

完成的操作
public class DbUser: IAutoMappingOverride<DbUser>
    {
        public void Override(AutoMapping<DbUser> mapping)
        {
            //tell it to do nothing now, probably tell it not to map to table,
            // not 100% on how you'd do this here.                    
        }
    }

或者你可以有一个属性

public class DoNotAutoPersistAttribute : Attribute
{
}

在AutoPersistenceModelGenerator中读取Where子句中的属性以将其排除。

检查就像是

private static bool CheckPeristance(Type t) { 
            var attributes = t.GetCustomAttributes(typeof (DoNotAutoPersistAttribute), true); 
            Check.Ensure(attributes.Length<=1, "The number of DoNotAutoPersistAttribute can only be less than or equal to 1"); 
            if (attributes.Length == 0) 
                return false;
            var persist = attributes[0] as DoNotAutoPersistAttribute; 
            return persist == null; 
        } 

那么这取决于你是如何添加实体的,但你可能是通过汇编添加的,所以这可能会为你做:

mappings.AddEntityAssembly(typeof(User).Assembly).Where(GetAutoMappingFilter);
....
...
private static bool GetAutoMappingFilter(Type t)
        {
            return t.GetInterfaces().Any(x => CheckPeristance(x)); //you'd probably have a few filters here
        }