2010-11-15 57 views
0

給定2個不相關的類,其中一個是 另一個繼承層次結構的成員,我如何映射兩個類的接口,以便我可以根據接口查詢並有 適當的具體類型返回? 例如使用NHibernate在多層次上映射接口

public abstract class Survey 
{ 
    public Guid Id { get; private set; } 
} 

public class InviteOnlySurvey : Survey 
{ 
    public ICollection<Invite> Invites { get; private set; } 
} 

public class Invite : ISurveyGateway 
{ 
    public Guid Id { get; private set; } 
    public InviteOnlySurvey Survey { get; private set; } 
} 

public class SharedSurvey : Survey, ISurveyGateway { ... } 

public interface ISurveyGateway 
{ 
    Guid Id { get; } 
} 

目前我一直在使用表每類層次結構,現在我試圖找出如何映射ISurveyGateway,這樣我就可以查詢它,並有NHibernate的找到匹配的實體(邀請或映射調查,InviteOnlyLiveSurvey和SharedLiveSurvey SharedLiveSurvey)無縫地。 ISurveyGateway實例是有效只讀的,因爲通過SharedSurvey和Invite的映射管理所有剩餘的持久性問題。

如果我從SharedSurvey或Invite中刪除ISurveyGateway接口,我可以通過NHibernate查詢和檢索ISurveyGateway實例,但只要我將接口應用於2個不同的層次結構,就會收到異常消息「ISurveyGateway的Ambiguous persister由多個層次實現「(這是預期的 - 我只是不知道如何使其工作)。

回答

0

鑑於Invite和SharedSurvey都已被映射和使用,並且由於Id是Guids,它確保不會有SharedSurvey和具有相同Id的Invite(具有相當高的確定性),我發現更簡單的方法。

public ISurveyGateway FindSurveyGatewayById(Guid id) 
{ 
    var sharedSurveyGateway = session.QueryOver<SharedSurvey> 
    .Where(s => s.Id == id) 
    .FutureValue<ISurveyGateway>(); 

    var inviteGateway = session.QueryOver<Invite> 
    .Where(i => i.Id == id) 
    .FutureValue<ISurveyGateway>(); 

    return sharedSurveyGateway.Value ?? inviteGateway.Value; 
} 

也有一些缺點與這 - 最主要的是這個查詢現在不得不延長被添加到系統中每個ISurveyGateway,但現在它用最少的複雜性和合理的工作性能。

1

與QueryOver和FutureValue答案的作品,但這裏有一個更簡單的解決方案:

public ISurveyGateway FindSurveyGatewayById(Guid id) 
{ 
    var surveyGateway = session 
    .QueryOver<ISurveyGateway> 
    .Where(s => s.Id == id) 
    .SingleOrDefault<ISurveyGateway>(); 
    return surveyGateway; 
} 

但你要小心,你的ID應該是一個GUID。如果不是這種情況,您可能會得到多個回覆...