2012-03-15 70 views
3

我在項目中使用NHibernate 3.1和Fluent NHibernate作爲ORM。我需要一個被Fluent NHibernate忽略的POCO屬性。起初,我的文章可能看起來像this question的確切副本,但事實並非如此。Fluent NHibernate忽略ClassMap內部的屬性,使用FluentMappings

我的複雜問題首先來自POCO是在與映射不同的組件中定義的事實,而我正在使用流利的映射作爲我的POCO。我有額外的要求,不要寫會話工廠配置發生的ingore屬性代碼(這發生在模塊外部的集中位置),而是作爲定義映射的模塊的一部分。理想情況下,我相信正確的地方將是具體的實現,因爲它知道如何向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(); 
    } 
} 
+0

你的映射類是什麼樣的,你的配置是什麼樣的? – shanabus 2012-03-15 20:30:06

+0

我通過添加一些代碼重新訪問了我的問題 – 2012-03-15 20:44:27

+0

另請參閱:http://stackoverflow.com/questions/5830649/how-do-you-make-nhibernate-ignore-a-property-in-a-poco – caspian311 2013-04-19 14:43:20

回答

5

我認爲你是對的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>(); 
       }); 
+0

好的,但這樣我需要知道每個類必須有一個屬性在集中式初始化位置忽略,並明確配置。這正是我想要避免的。想象一下,如果我必須重構一個模塊,我也必須修改應用程序的ORM初始化。 – 2012-03-15 20:43:08

+0

在你的問題中,你說:「我有額外的要求,不要設置在會話工廠配置(發生在集中的地方)設置屬性,而是作爲定義映射的模塊的一部分。」但是現在你說這是我答案的問題?也許我不明白你在問什麼,對不起。 – shanabus 2012-03-15 21:14:00

+0

對不起,我有一個錯誤的印象,認爲重寫發生在會話工廠正在配置的集中地點,我的不好。覆蓋界面可以放在我定義映射的同一個程序集中。 – 2012-03-15 21:44:23

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(); 
+0

有趣的方法!如果只是我不必讓我的實體保持與ORM相關的註釋清潔(我在單獨的程序集中有映射,所以我可以在不帶任何orm依賴的情況下從其他程序集中重用我的實體類)。我會嘗試通過我的映射類來實現上述效果。 – 2012-12-19 14:58:05

+0

這會忽略任何有任何屬性的屬性。可能不期望或預期的行爲。 – 2015-04-02 02:26:11

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 
}