Fluent NHibernate使用FluentMappings忽略ClassMap中的属性

时间:2012-03-15 20:18:06

标签: c# nhibernate orm fluent-nhibernate

我在我的项目中使用NHibernate 3.1和Fluent NHibernate作为ORM。我需要Fluent NHibernate忽略POCO的属性。首先,我的帖子可能看起来与this question完全相同,但事实并非如此。

我的并发症首先来自这样一个事实,即POCO的定义与映射不同,而且我正在使用流畅的映射来进行POCO。我还有其他要求,不要在会话工厂配置发生时编写ingore-property代码(这发生在模块外部的集中位置),而是作为定义映射的模块的一部分。理想情况下,我认为正确的地方是具体的ClassMap实现,因为它确切地知道如何向ORM描述POCO。

但是,我坚持这个主要是因为这是我对NHibernate及其流畅的API的第一次影响。到目前为止,我对其功能和可扩展性有非常好的印象,我希望有一种方法可以通过将映射相关代码封装在相应模块中的方式来实现我的需求。

以下是我的配置,来自集中的地方:

List<Assembly> assemblies = GetModules().Select(x => x.GetType().Assembly).ToList();

ISessionFactory nhibernateSessionFactory = Fluently
    .Configure()
    .Mappings(m => assemblies.ForEach(asm => m.FluentMappings.AddFromAssembly(asm)))
    .Database(
        MsSqlConfiguration.MsSql2005
            .ShowSql()
            .ConnectionString(DatabaseConfig.Instance.ConnectionString))
    .ExposeConfiguration(c => new SchemaUpdate(c).Execute(true, true))
    .BuildSessionFactory();

我使用从ClassMap继承的标准类映射:

public class User
{
    public virtual int ID { get; set; }
    public virtual String Username { get; set; }
    public virtual String Password { get; set; }
    public virtual DateTime DateCreated { get; set; }
    public virtual DateTime DateModified { get; set; }

    // Must ignore
    public string ComputedProperty  { get { ... } }
}

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        Table("User");
        Id(x => x.ID).GeneratedBy.Identity();
        Map(m => m.Username).Not.Nullable().Length(255).UniqueKey("User_Username_Unique_Key");
        Map(m => m.Password).Not.Nullable().Length(255);
        Map(m => m.DateCreated).Not.Nullable();
        Map(m => m.DateModified).Not.Nullable();
    }
}

3 个答案:

答案 0 :(得分:5)

我知道这篇文章有点老了,但我还是发帖了,因为我没有找到关于这个主题的任何最新帖子。 我想最简单的方法应该是为每个我们不希望持久保存到表的属性添加属性。通过添加一个扩展,检查它是否有例如。有一个[NoEntity] attibute。

/// <summary>
/// Tells a single Property to not be persisted to table.
/// </summary>
public class NoEntity : Attribute { }


    /// <summary>
/// Extension to ignore attributes
/// </summary>
public static class FluentIgnore
{
    /// <summary>
    /// Ignore a single property.
    /// Property marked with this attributes will no be persisted to table.
    /// </summary>
    /// <param name="p">IPropertyIgnorer</param>
    /// <param name="propertyType">The type to ignore.</param>
    /// <returns>The property to ignore.</returns>
    public static IPropertyIgnorer SkipProperty(this IPropertyIgnorer p, Type propertyType)
    {
        return p.IgnoreProperties(x => x.MemberInfo.GetCustomAttributes(propertyType, false).Length > 0);
    }
}

在流畅的配置设置中:

            return Fluently.Configure()
            .Database(DatabaseConfig)
            .Mappings(m => m.AutoMappings.Add(AutoMap.Assembly(typeof(IDependency).Assembly)
            .OverrideAll(p => {
                p.SkipProperty(typeof(NoEntity)); 
            }).Where(IsEntity)))
            .ExposeConfiguration(ValidateSchema)
            .ExposeConfiguration(BuildSchema)
            .BuildConfiguration();

答案 1 :(得分:4)

我认为你是对的,ClassMap是忽略这个属性的最佳位置。

示例:

.Override<Shelf>(map =>  
{  
  map.IgnoreProperty(x => x.YourProperty);
});

文档:https://github.com/jagregory/fluent-nhibernate/wiki/Auto-mapping#ignoring-properties

至于从另一个程序集获取映射,它应该像这样简单(取决于您当前的配置):

.Mappings(m =>
              {
                  m.FluentMappings.AddFromAssemblyOf<ProvideClassFromYourOtherAssembly>();
              });

答案 2 :(得分:0)

不会贾斯汀。这是这个扩展的事情。只是您想要的属性被忽略。

public class Person : IEntity{ 
 public virtual string Name{..}
 public virtual string Lastname{..}

 [NoProperty]
 public virtual string FullName{ // Not created property
  get { return Name +  " " + Lastname;  }
 }
}

public class Group : IEntity{ 
 public virtual string FullName{..} //Created property
}