NHibernate 3.1忽略计算列公式

NHibernate 3.1忽略计算列公式,nhibernate,fluent-nhibernate,Nhibernate,Fluent Nhibernate,我有一个有两个计算列的类。这些公式是select语句,用于从其他表中获取计数,如下所示: private const string VOTES_FORMULA = "(select count(v.id) from Votes v where v.BusinessID = Id)"; private const string SURVEY_FORMULA = "(select cast((case when exists (select * from surveys s where s.busi

我有一个有两个计算列的类。这些公式是select语句,用于从其他表中获取计数,如下所示:

private const string VOTES_FORMULA = "(select count(v.id) from Votes v where v.BusinessID = Id)";
private const string SURVEY_FORMULA = "(select cast((case when exists (select * from surveys s where s.businessid = Id) then 1 else 0 end) as bit))";

// in my bootstrap code...
mappings.Override<Business>(map =>
{
    map.IgnoreProperty(x => x.IsNewRecord);
    map.IgnoreProperty(x => x.IdString);
    map.Map(x => x.UserPassword).CustomType<EncryptedStringType>();
    map.Map(x => x.HasTakenSurvey).Formula(SURVEY_FORMULA).Not.Insert().Not.Update();
    map.Map(x => x.Votes).Formula(VOTES_FORMULA).Not.Insert().Not.Update();
});
在使用NHibernate 2.1的Fluent NHibernate 1.1中,这一切都很好,但我刚刚使用NH3.1升级到1.2,看起来Fluent NHibernate忽略了公式。我得到了两个字段HasTakenSurvey和vots的无效列名异常,因为它试图直接查询列,而不是按照指示执行公式。一个示例查询:

exec sp_executesql N'select TOP@p0 business0.Id为Id0_,business0_。userpass为UserPass2_,business0_。HasTakenSurvey为hastaken 3_0,business0_。投票为Votes0,business0_。来源为Origin0_,business0_。SecurityToken为Security6_,business0_0。BusinessName为Business7_0,business0。BusinessType为Business8_0,business0.BusinessImageUrl为Business9.0,business0.BusinessDescription为business10.0,business0.employees为employee11.0,business0.OwnerFirstName为OwnerFi12.0,business0.OwnerLastName为ownerA13.0,business0.UserPosition为userPosition14.0,business0.BusinessAddress1为business15.0,business0.BusinessAddress2作为business16.0,business0.0作为business17.0,business0.BusinessState作为business18.0,business0.BusinessPostal作为business19.0,business0.BusinessCountry作为business20.0,business0.UserBusinessPhone作为userbusiness21.0,business0.UserMobilePhone作为UserMob22.0,business0.UserEmailAddress作为UserEma23.0,business0.UserIpAddress作为UserIpA24\u 0\u,business0\u。OptInReminders作为OptInRe25\u 0\u,business0\u。OptInOffers作为optinFor26\u 0\u,business0\u。optinMs作为optinMs0\u,business0\u。创建为Created0\u,business0\u。修改为来自dbo的Modified0\u。Businesses business0\u按business0\u订购。BusinessName asc','@p0 int',@p0=25


实施有变化吗?我做错了什么?

正如评论ConventionBuilder.Property.Alwaysx=>x.Columnx.Property.Name中指出的那样,将列添加到所有属性并覆盖公式

将.Columns.Clear添加到映射中会删除该列,因此:

mappings.Override<Business>(map =>
{
    map.IgnoreProperty(x => x.IsNewRecord);
    map.IgnoreProperty(x => x.IdString);
    map.Map(x => x.UserPassword).CustomType<EncryptedStringType>();
    map.Map(x => x.HasTakenSurvey).Formula(SURVEY_FORMULA).Not.Insert().Not.Update().Columns.Clear();
    map.Map(x => x.Votes).Formula(VOTES_FORMULA).Not.Insert().Not.Update().Columns.Clear();
});

@david duffet提供的清晰解决方案也不适合我。Formula的getter是私有的,因此您不能对获取的Formula属性进行筛选。方法组不能转换为值或类似的内容。NH3.3,FNH 1.3

我的解决方案-在我的模型项目中创建自定义属性-IsNHibernateFormulaPropertyAttribute,将其应用于我的公式属性,然后使用反射在我的命名约定逻辑中检查该属性:

private bool IsFormula(IPropertyInstance instance)
{
    var propInfo = instance.Property.DeclaringType.GetProperty(instance.Property.Name);
    if (propInfo != null)
    {
        return Attribute.IsDefined(propInfo, typeof(IsNHibernateFormulaPropertyAttribute));
    }

    return false;
}
public void Apply(IPropertyInstance instance)
    {
        if (!IsFormula(instance))
        {
            instance.Column(Convert(instance.Property.Name));
        }
    }

您是否有一个FluentNHibernate属性约定设置,可以为每个属性添加一列?我以前就被这个问题困扰过,不得不为公式中的属性添加一个排除项。为什么是这样,我有ConventionBuilder.Property.Alwaysx=>x.Columnx.Property.Name。如何从此约定中排除公式列?是否尝试将.columns.Clear添加到每个属性的映射覆盖中?但是,如果在映射重写之后执行您提到的属性约定,则可能会有问题。我在实现IPropertyConvention和IPropertyConventionAcceptance的单独类中设置映射重写,并在Accept方法中排除Formula属性不为null的情况。我需要将其与映射中的.Columns.Clear结合起来,因为不能保证应用约定的顺序。Columns.Clear做到了这一点。作为答案发布,以便我可以接受:PColumns.Clear对我不起作用。我必须实现IPropertyConvention接口和过滤器公式property@MadRabbit你是怎么做到的?你能告诉我更多吗