NHibernate — присоединиться без маппинга

Можно ли объединить два класса без указания сопоставления между ними (используя Criteria API)?

Я должен присоединиться к двум классам и получить данные из обоих, но я не могу их сопоставить. Я знаю только внешний ключ SomeID в первом классе и первичный ключ ID во втором.

Как создать Критерии, чтобы присоединиться к ним? Можно ли без маппинга?

Пожалуйста, помогите, мне это очень нужно, но я застрял. :/

PS

Я знаю "любое" сопоставление, но у меня есть 10 полей, таких как SomeID. Создавать какие-либо сопоставления для 10 полей только для создания объединений — это перебор. Если нет другого решения, я сделаю это, но я не хочу.


person dariol    schedule 05.02.2009    source источник


Ответы (2)


Я не знаю версию критериев, но в HQL вы можете сделать это так:

select customer, order from Customer customer, Order order 
    where order.CustomerID = customer.Id
    and customer.Id = 42

Результирующий набор тогда будет списком object[], где клиент будет повторяться, умноженное на количество размещенных им заказов (конечно, при условии, что есть один клиент для многих заказов).

Обратите внимание, что результат будет пустым, если заказов нет.

person mookid8000    schedule 05.02.2009
comment
Да. Я использую его по критериям. Я ищу возможность создать что-то вроде этого: выберите клиента, заказ от клиента клиента, заказ заказа, пользователь, пользователь, где order.SomeID_1 = customer.Id order.SomeID_2 = user.Id Я не знаю во время разработки, что поле SomeID_xxx содержит. :/ - person dariol; 05.02.2009
comment
Ладно, я понял. HQL — это только один из вариантов. - person dariol; 18.01.2010
comment
Удалось ли вам создать для него запрос критериев? если да, пожалуйста, напишите .. к сожалению, я в такой же ситуации :( - person Illuminati; 21.01.2011

Если вы не хотите или не можете определить свойства ассоциации в своих объектах (например, в модульных приложениях, которые поддерживают динамическую загрузку плагинов), вы все равно можете создавать «поддельные» ассоциации с помощью API Fluent.

См. исходный код Orchard, класс ContentItemAlteration. В Orchard сущность ContentItem требуется соединить с записями ContentPart, хранящимися в разных таблицах. Каждый тип ContentPart предоставляется модулями, что означает, что сложно (и, вероятно, нежелательно) изменить источник ContentItem и добавить ассоциацию для каждой новой записи части.

Вот точный код, который я получил из источников Orchard:

/// <summary>
    /// Add a "fake" column to the automapping record so that the column can be
    /// referenced when building joins accross content item record tables.
    /// <typeparam name="TItemRecord">Either ContentItemRecord or ContentItemVersionRecord</typeparam>
    /// <typeparam name="TPartRecord">A part record (deriving from TItemRecord)</typeparam>
    /// </summary>
    class Alteration<TItemRecord, TPartRecord> : IAlteration<TItemRecord> {
        public void Override(AutoMapping<TItemRecord> mapping) {

            // public TPartRecord TPartRecord {get;set;}
            var name = typeof(TPartRecord).Name;
            var dynamicMethod = new DynamicMethod(name, typeof(TPartRecord), null, typeof(TItemRecord));
            var syntheticMethod = new SyntheticMethodInfo(dynamicMethod, typeof(TItemRecord));
            var syntheticProperty = new SyntheticPropertyInfo(syntheticMethod);

            // record => record.TPartRecord
            var parameter = Expression.Parameter(typeof(TItemRecord), "record");
            var syntheticExpression = (Expression<Func<TItemRecord, TPartRecord>>)Expression.Lambda(
                typeof(Func<TItemRecord, TPartRecord>),
                Expression.Property(parameter, syntheticProperty),
                parameter);

            mapping.References(syntheticExpression)
                .Access.NoOp()
                .Column("Id")
                .ForeignKey("none") // prevent foreign key constraint from ContentItem(Version)Record to TPartRecord
                .Unique()
                .Not.Insert()
                .Not.Update()
                .Cascade.All();
        }
    }

Этот код просто добавляет ассоциацию «часть» к ContentItem, что позволяет вам использовать объединения в ваших критериях. Если, например, у вас есть часть с именем «ProductPart», которая хранится в таблице с именем «ProductPartRecord», вы можете присоединиться к своему ContentItem на поддельном свойстве «ProductPartRecord».

Кстати, кажется, что эту тактику можно применить и к HasMany стороне поддельного отношения, но я полагаю, что вам нужно настроить источники Fluent.

person Cagatay Kalan    schedule 21.11.2012