Свободное соединение NHibernate по нескольким полям - PullRequest
0 голосов
/ 10 января 2012

В настоящее время я изучаю, как перенести уровень доступа к данным существующего веб-приложения .NET 4.0 MVC 3 на платформу сущностей. Есть много причин, но основная из-за тысяч хранимых процедур, добавление только 1 поля в таблицу приводит к 30 - 50 sproc правкам !!

Мы используем MS SQL Server 2008 R2 и, в идеале, мы хотели бы использовать NHibernate и Fluent для отображения.

Я упростил задачу, которую я имею, в простой пример:

Представьте себе следующие 2 таблицы:

Таблица «Продукты»

ID (INT)
DefaultName (NVARCHAR(128))

Таблица наименований продуктов

ProductID (INT)
Name (NVARCHAR(128))
Culture (VARCHAR(10))

Таблица «Продукты» будет содержать список продуктов, каждый из которых будет иметь название по умолчанию на английском языке. Таблица Product Names будет содержать идентификатор продукта и множество переводов.

В настоящее время, используя хранимые процедуры, мы имеем следующее:

SELECT Products.ID,
       ISNULL(ProductNames.Name, Products.DefaultName) AS Name
FROM Products
LEFT JOIN ProductNames ON ProductNames.ProductID = Products.ID AND ProductNames.Culture = @Culture;

Примечание: @Culture передается в процедуру

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

Мой вопрос: возможно ли это сделать на уровне картирования Fluent NHibernate? Я искал несколько дней на тему «Как объединить две колонки», но не могу найти решение, которое работает. Казалось бы странным, если это невозможно в таких зрелых рамках?

В качестве примера того, с чем я экспериментировал:

public class ProductMap : ClassMap<Product> {
  public ProductMap() {
    Id(p => p.Id);

    Join("ProductNames", pn => {
      pn.Optional()
        .KeyColumn("ProductID")
        .Map(p => p.Name);
    });
  }
}

Однако это приводит к следующему исключению:

More than one row with the given identifier was found: 109, for class: Product

Это потому, что продукт 109 имеет 5 переводов и, следовательно, все 5 не могут быть сопоставлены одной строке.

Мне удалось использовать метод 'HasMany <>' для отображения всех переводов в Список в Продукте. Однако это не то, что мне нужно.

1 Ответ

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

если имя только для чтения, то

public class ProductMap : ClassMap<Product> {
    public ProductMap() {
        Id(p => p.Id);

        Map(p => p.Name).Formula("Select ISNULL(pn.Name, DefaultName) FROM ProductNames pn WHERE pn.ProductID = ID AND pn.Culture = '" + GetCUltureFromSomewhere() + "'");
    }
}
...