Отображение подкласса с несколькими "ролями" - PullRequest
0 голосов
/ 09 августа 2011

сложная проблема - пожалуйста, потерпите меня.Любая помощь с благодарностью.

У меня есть таблица / класс Contact (PK Id) и два производных клиента и должника (PK и FK ContactId).Case 4-й таблицы имеет внешние ключи для должника и клиента (приведенные ниже сопоставления).

Сначала все работало нормально.Но затем я получаю некоторые данные, когда один и тот же контакт является клиентом в одном деле, а должником - в другом.Если они читаются в одном запросе nhibernate, например Session.Query<Case>().Fetch(c => c.Debtor).Fetch(c => c.Client), появляется

NHibernate.WrongClassException
    "Object with id: {someGuid...} was not of the specified subclass: Client 
    (loading object was of wrong class [Debtor])

Похоже, что кэш первого уровня сеанса распознает запись по его идентификатору и пытается избежать чтения данных из набора результатов sql,Конечно, приведение NH считает необходимым, чтобы повторное использование не удалось.

К сожалению, изменение схемы БД не вариант.Это устаревшая система.(и схема в порядке и чиста ИМО)

Не знаю, важно ли это: класс Contact не является абстрактным.Используются контакты, которые не являются ни клиентами, ни должниками.

Есть ли шанс заставить это работать с этими многоконтактными контактами?Заранее спасибо.

public partial class ContactMap : ClassMap<Contact>
{
    public ContactMap()
    {
    Id(x=>x.Id).GeneratedBy.Guid();
    Map(x=>x.FirstName);
    Map(x=>x.Name1).Not.Nullable();
        ...
    }
}
public class DebtorMap : SubclassMap<Debtor>
{

    public DebtorMap()
    {
        KeyColumn("ContactID");
        Table("[dbo].[Debtor]");
        Map(x => x.MaritalStatus);
        ...
    }
}

public partial class ClientMap : SubclassMap<Client>
{

    public ClientMap()
    {
        KeyColumn("ContactID");            
        Map(x => x.ClientNo).Not.Nullable();
        ...
    }
}

public partial class CaseMap : ClassMap<Case>
   public CaseMap()
   {
       ...
       References<Client>(x=>x.Client)
       References<Debtor>(x=>x.Debtor)
       ...
    }    

1 Ответ

0 голосов
/ 10 августа 2011

Если вы можете добавить представление к схеме, вы можете создать представление с именем Roles, которое объединяет записи как клиента, так и должника.Затем вы можете изменить свою объектную модель для представления ролей:

class Contact
{
    public virtual Guid Id { get; set; }
    public virtual string FirstName { get; set; }
    public virtual ICollection<Role> Roles { get; private set; }
}

class Role
{
    public virtual Guid Id { get; set; }
}

class Client : Role
{
    public virtual string ClientNo { get; set; }
}

class Debtor : Role
{
    public virtual string MaritalStatus { get; set; }
}

class ContactMap : FluentNHibernate.Mapping.ClassMap<Contact>
{
    public ContactMap()
    {
        Table("dbo.Contacts");
        Id(x => x.Id).GeneratedBy.GuidComb();
        Map(x => x.FirstName);
        HasMany(x => x.Roles)
            .KeyColumn("ContactId")
            .Not.LazyLoad()
            .Fetch.Join();
    }
}

class RoleMap : FluentNHibernate.Mapping.ClassMap<Role>
{
    public RoleMap()
    {
        Table("dbo.Roles");
        Id(x => x.Id).GeneratedBy.GuidComb();
        this.Polymorphism.Implicit();
    }
}

class ClientMap : FluentNHibernate.Mapping.SubclassMap<Client>
{
    public ClientMap()
    {
        Table("dbo.Clients");
        KeyColumn("Id");
        Map(x => x.ClientNo);
    }
}

class DebtorMap : FluentNHibernate.Mapping.SubclassMap<Debtor>
{
    public DebtorMap()
    {
        Table("dbo.Debtors");
        KeyColumn("Id");
        Map(x => x.MaritalStatus);
    }
}

Поскольку таблица контактов теперь совместно использует PK с таблицами клиента и должника, это должно работать.Вид ролей будет выглядеть примерно так:

create view dbo.Roles as

select 
    Id,
    ContactId
from dbo.Clients

union all

select 
    Id,
    ContactId
from dbo.Debtors
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...