2012-07-12 57 views
2

我有一個有趣的感覺,這只是我對nHibernate和Fluent nHibernate的理解。流利nhibernate功能不正確生成架構

我有一個小的控制檯應用程序,它根據一堆實體類導出模式。一切工作很好,直到我這樣做:

public virtual int UserId { get; set; } 
    public virtual string FirstName { get; set; } 
    public virtual string LastName { get; set; } 
    public virtual string Email { get; set; } 
    public virtual UserType UserType { get; set; } 
    public virtual Client Client { get; set; } 
    public virtual string UniqueIdentifier { get; set; } 

    public virtual IList<UserAttribute> UserAttributes { get; set; } 

    /** CODE IN QUESTION **/ 
    public virtual string GetAttributeValue(string name) 
    { 
     var value = UserAttributes.FirstOrDefault(ua => ua.AttributeDefinition.AttributeName == name); 
     if (value != null) 
      return value.Value; 
     else 
      return string.Empty; 
    } 

如果我註釋掉的功能,一切都很好。即使我只有函數返回字符串.Empty,一切正常。但是,一旦我重新添加一行:

var value = UserAttributes.FirstOrDefault(ua => ua.AttributeDefinition.AttributeName == name); 

一切都改變了這個錯誤:

"The entity '<>c__DisplayClass1' doesn't have an Id mapped. Use the Id method to map your identity property. For example: Id(x => x.Id)." 

我使用自動映射。這個錯誤的原因是什麼?我通常瞭解錯誤,但看起來它在匿名類上失敗。對於這一切應該如何一起工作,我是否有一個錯誤的誤解?我絕對是nHibernate的新手,無論是在實踐中還是在哲學上。我很想開悟!

回答

6

lambda ua => ua.AttributeDefinition.AttributeName == name生成一個內部類來捕獲名稱參數。自動映射器遍歷每一種類型並嘗試映射它,並且不幸地也選擇了編譯器生成的一個。

你可以實現一個AutomappingConfiguration排除編譯器生成的類

class MyAutomappingConfiguration : DefaultAutomappingConfiguration 
{ 
    public override bool ShouldMap(Type type) 
    { 
     return !type.IsDefined(typeof(CompilerGeneratedAttribute), false) && base.ShouldMap(type); 
    } 
} 
+0

Firo - 我的膝蓋混亂反應是,這種行爲是Automapping中的錯誤 - 你會同意嗎? – 2012-07-12 14:59:24

+0

我自己也在想同一件事......這看起來不錯,我會在接下來的一個小時左右對它進行測試。 – 2012-07-12 18:02:17

+0

@TomBushell我會這麼說。如果是這樣,請提出問題。 – Firo 2012-07-12 19:19:21

0

雖然,@Firo回答上面的作品,它似乎並沒有當你有另一個Linq查詢中的LINQ查詢工作。例如:

DataTable Dt = FillData(); 
EnumerableRowCollection<DataRow> MasterProfileRows = null; 
IList<RecordOwner> OwnedRecs = new List<RecordOwner>(); 
OwnedRecs.Add(new RecordOwner { ForeignRecordKey = 100 }); 
MasterProfileRows = from x in dt.AsEnumerable() 
        where OwnedRecs.Any(y => y.ForeignRecordKey.ToString() == x.Field<object>("ProfileID").ToString()) 
        select x; 

要解決這個問題,我加入到這個我重寫,以檢查在類的全名,如果該值大於1,我們忽略了它映射「__displayclass」的出現次數。

public override bool ShouldMap(Type type) 
{ 
    // there is a bug where the fluent automapper tries to automap anonymous types within a lambda. the !type.IsDefined(typeof(CompilerGeneratedAttribute), false) works around this issue 
    // except where there is a nest linq query. 
    // see: 
    // https://github.com/jagregory/fluent-nhibernate/issues/146 
    // http://stackoverflow.com/questions/11446155/fluent-nhibernate-not-generating-schema-correctly-on-function/11447966#11447966 
    // http://stackoverflow.com/questions/14268568/odd-error-building-fluentnh-configuration 
    // http://stackoverflow.com/questions/11446155/fluent-nhibernate-not-generating-schema-correctly-on-function/11447966 
    // ignore nested linq queries (linq queries within linq queries) because they cause the auto mapper to error out. 
    System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex("__displayclass", System.Text.RegularExpressions.RegexOptions.IgnoreCase); 
    if(reg.Matches(type.FullName).Count > 1) 
     return false; 

    return !type.IsDefined(typeof(CompilerGeneratedAttribute), false); 
}