Как отобразить представление без столбца идентификаторов в NHibernate?

У меня есть мнение, что я собираюсь только читать (без записи). Это представление не имеет уникального ключа (не составного события).

Так как я могу отобразить этот вид в NHibernate, не касаясь вида? Я не хочу добавлять новый столбец в представление, чтобы создать для меня уникальную личность. Есть ли способ отобразить это представление и создать столбец идентификаторов на стороне NHibernate?

Я могу сгенерировать GUID в моем классе сущности, например:

public class MyViewClass
{
    private Guid _id = new Guid();
    public virtual Guid Id { get { return _id; } set { _id = value; } }
}

Но как я могу заставить отображение работать? Следующий код не работает:

public class MyViewClass: ClassMapping<MyViewClass>
{
    public MyViewClass()
    {
        Mutable(false);
        Id(x => x.Id, m => m.Generator(Generators.Guid));
    }

} 

Предполагается, что столбец Id будет виден, и выдает:

System.Data.SqlClient.SqlException: Invalid column name 'Id'.

Кстати, я использую NHibernate 3.2 и отображение по коду.

2 ответа

Обновление: чтобы использовать его в LINQ сопоставить все столбцы как CompositeId Mutable(false) затем переопределяет Equals и GetHashCode с реализацией по умолчанию.

public class MyViewClass
{
    public override bool Equals(object obj)
    {
        return base.Equals(obj);
    }

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
}

оригинальный ответ:

я бы вообще не отображал его, если вы не хотите его вставлять / обновлять

public class MyViewClass
{
    public virtual string Prop1 { get; set; }
    public virtual int Prop2 { get; set; }
}

var viewObjects = session.CreateSQLQuery("SELECT col1 as Prop1, col2 as Prop2 FROM MyView")
    .SetResultTransformer(Transformers.AliasToBean<MyViewClass>())
    .List<MyViewClass>();

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

  1. Добавьте столбец идентификатора. В моем случае, поскольку мое представление представляет собой сводку таблицы со столбцом Id, я просто добавил столбец Id также в определение представления.
  2. Добавьте составной идентификатор из нескольких столбцов в классе сопоставления.

В классе отображения мне также нужно было добавить, в противном случае NHibernate во время выполнения будет жаловаться на то, что он не может сопоставить объект с таблицей/представлением.

Класс сопоставления будет выглядеть следующим образом (выберите вариант 1 или 2):

      public class EntityMap : ClassMapping<Entity> {

  public EntityMap() {
    SchemaAction(NHibernate.Mapping.ByCode.SchemaAction.None);
    Table("NameOfTheView");
    Mutable(false);

    // Option 1
    Id(e => e.Id, map => map.Column("Id"));

    // Option 2
    // NOTE: With ComposedId you need to override Equals() and GetHashCode() in the entity class
    ComposedId(map => {
      map.Property(e => e.Column1);
      map.Property(e => e.Column2);
    });

    // Additional mapping code
  }
}

Я также предпочитаю сопоставлять представление с сущностью, потому что тогда я могу использовать API QueryOver или Query (LINQ), чтобы исключить использование магических строк (имен таблиц/столбцов) в обычном SQL-запросе.

Другие вопросы по тегам