FluentNHibernate: как обращаться со значениями «один ко многим», когда «множество» является простым перечислением - PullRequest
2 голосов
/ 01 сентября 2010

Кажется, что следующий сценарий не должен быть редкостью, но я не могу понять, как справиться с этим в FluenNHibernate:

public class Product: BaseEntity
{
    public Product()
    {
        Categories = new List<Category>();
    }

    public virtual IList<Category> Categories { get; set; }
    ...
}

public enum Categories
{
    Classic = 1,
    Modern = 2,
    Trendy = 3,
    ...
}

Итак, мне нужна таблица ProductCategories, которая позволяет мне сопоставить один продукт со многими категориями, но я не думаю, что NHibernate справится с этим, если у меня нет фактического класса Categories и таблицы Categories с отношением многие ко многим. указано. Есть ряд причин, по которым это нежелательно, и не в последнюю очередь это то, что это излишне.

Я использую AutoMapper - можно ли как-нибудь переопределить эту работу?

Спасибо!

Ответы [ 4 ]

4 голосов
/ 01 декабря 2010

Этот принятый ответ работал для меня, однако перечисление было отображено как в int.

Чтобы отобразить его как строку (мое предпочтение), я настроил отображение следующим образом:

public void Override(AutoMapping<Account> mapping)
{
    mapping
        .HasMany(x => x.Categories)
        .Table("CategoriesProductsMap")
        .Element("Category", e => e.Type<NHibernate.Type.EnumStringType<Category>>())
        .AsSet();
}
2 голосов
/ 02 сентября 2010

Я пробовал объединенную строку в другом примере, подобном этому, но я действительно хотел что-то, что не нужно каждый раз преобразовывать.Как оказалось, я нашел очень похожий вопрос здесь: Карта списка Enums? .Как описано там, это переопределение работает:

public void Override(AutoMapping<Product> mapping)
{
     mapping.HasMany(x => x.Categories).KeyColumn("ProductFk").Table("CategoriesProductsMap").Element("Category").AsBag();
}
0 голосов
/ 01 сентября 2010

На работе, хотя это не относится к коллекции значений перечисления, мы создали собственный тип (реализовав IUserType для хранения IDictionary<CultureInfo, string>.

Мы преобразовали словарь в документ xml (XDocument), и мы сохранили данные в столбце Xml на Sql Server, хотя любое строковое столбец может хранить значение.

Вы можете просмотреть этот сайт для получения информации о реализации IUserType.

0 голосов
/ 01 сентября 2010

Есть несколько способов сделать это, ни один из них не так прост, как вы могли бы ожидать.В то время как NHibernate и Fluent NHibernate довольно хорошо справляются с одним enum, для коллекции значительно больше проблем.

Вот несколько подходов:

  1. Сохранение коллекции в одномnvarchar(?) столбец путем объединения членов.
  2. Пометьте enum атрибутом Flags и сверните список как битовую маску (для этого потребуется только один целочисленный столбец)

В любом случае вы можете иметь NHibernate доступ к полю, содержащему «свернутые» значения;Получатели открытых свойств преобразуют свернутые значения в коллекции.Получатель свернутого значения преобразует коллекцию в одну строку (1) или целое число (2).

Вы должны явно отобразить Product:

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

        Map(Reveal.Member<Product>("_categories"))
            .Access.Field();
    }
}

Такхотя Product предоставляет IList<Category>, NHibernate будет только получать и устанавливать значение поля _categories;

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