Сопоставление интерфейса с несколькими иерархиями с помощью NHibernate - PullRequest
0 голосов
/ 15 ноября 2010

Учитывая 2 несвязанных класса, один из которых является членом другой иерархии наследования, как я могу сопоставить интерфейс для обоих классов, чтобы я мог выполнять запросы к интерфейсу и получить соответствующий конкретный тип?Например,

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; } 
} 

. В настоящее время я сопоставил Survey, InviteOnlyLiveSurvey и SharedLiveSurvey, используя таблицу для каждой иерархии классов, и теперь я пытаюсь выяснить, как сопоставить ISurveyGateway, чтобы я мог выполнить запрос к нему и дать NHibernate найти соответствующую сущность.(Пригласить или SharedLiveSurvey) без проблем.Экземпляры ISurveyGateway эффективно доступны только для чтения, поскольку все остающиеся проблемы постоянства управляются с помощью сопоставлений для SharedSurvey и Invite.

Если я удаляю интерфейс ISurveyGateway из SharedSurvey или Invite, я могу запрашивать и получать экземпляры ISurveyGateway через NHibernate, нокак только я применяю интерфейс к двум различным иерархиям, я получаю исключение с сообщением «Неоднозначное сохранение для ISurveyGateway, реализованного несколькими иерархиями» (что ожидается - я просто не знаю, как заставить это работать).

Ответы [ 2 ]

1 голос
/ 09 января 2012

Ответ с QueryOver и FutureValue работает, но вот еще более простое решение:

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

Но вы должны быть осторожны, ваш идентификатор должен быть Guid.Если это не так, вы можете получить несколько ответов ...

0 голосов
/ 16 ноября 2010

Учитывая, что и Пригласить, и SharedSurvey уже сопоставлены и используются, а также потому, что идентификаторы являются направляющими, что гарантирует отсутствие SharedSurvey и приглашения с одинаковым идентификатором (с довольно высокой степенью достоверности), я обнаружил, чтоболее простой подход.

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, добавляемого в систему, но пока он выполняет работу снаименьшая сложность и разумная производительность.

...