Вопрос

Вдохновленный шумихой вокруг DDD, я разработал свои классы, притворяясь, что базы данных вообще нет.А затем использовал NHibernate для сопоставления классов с таблицами базы данных.Часть моего графа классов выглядит так:Заказ (имеет много) --> Товар (принадлежит) --> Продавец.Чтобы получить все заказы, размещенные для определенного продавца.У меня есть код:

public class Order:ActiveRecordBase<Order>
{
    [HasMany]
    public ICollection<Product> Items{get;set;}
    ...
}

public class Product: Order:ActiveRecordBase<Product>
{
    [BelongsTo]
    public Seller Seller{get; set;} 
    ...
}

public class OrderRepository:IOrderRepository
{
    public IQuerable<Order> GetOrdersBySellerId(int sellerId)
    {
        return Order.FindAll().AsQuerable.Where(x=>x.Items.Count > 0 &&
                                                   x.Items.First().Seller.SellerID == sellerId).AsQuerable();

    }
}

Некрасиво, но с моими модульными тестами это сработало.Я был счастлив, пока мы не начали вводить в базу данных реальные данные.Спектакль настолько плох, что меня стошнит.Итак, я провел небольшое исследование кода моего репозитория.Неудивительно, что для того, чтобы найти нужные мне заказы, мне пришлось получить все данные из таблицы «Заказ», все данные из таблицы «Продукт» и некоторые данные из таблицы «Продавец».

Итак, вот и моя проблема.Будучи полным дураком в области баз данных, я не знаю, как улучшить код своего репозитория, хотя знаю, что он ужасно воняет.Итак, у меня возникает соблазн изменить свой класс Order, чтобы он имел ссылку на класс Seller, чтобы я мог использовать hql для добавления предложения Where для повышения производительности.Но изменение структуры классов из-за проблемы с базой данных, похоже, нарушает принципы DDD.

Что вы предлагаете, особенно по улучшению кода моего репозитория?Я пробовал Linq для ActiveRecord и hql.Но заставить их работать не удалось.

Это было полезно?

Решение 2

После долгих исследований я получил это заявление hql

public IQuerable<Order> GetOrdersBySellerId(int sellerId)
{
     string hql = @"select  o 
                    from     Order o, Product p
                    where    p.Seller.SellerID=:sellerID
                    and      p in elements(o.Items )";

     SimpleQuery<Order> q = new SimpleQuery<Order>(hql);
     q.SetParameter("sellerID", sellerID);
            return q.Execute().AsQueryable();
}

Спасибо этот почта.Я получил эту идею из ответа Айенде.Пожалуйста, дайте мне знать, если это загрузит производительность.

Другие советы

Хотя AFAIK ActiveRecord не имеет прямой поддержки LINQ, вы можете использовать поставщика LINQ to NHibernate. Здесь является образцом.В конце приведен пример использования более традиционных и зрелых критериев API.

ОБНОВЛЯТЬ:Извините, я ошибся.Кажется, вам нужно наследовать свои сущности от ActiveRecordLinqBase<T>, и строить запросы, используя его Queryable свойство.

Это должно выглядеть так

public IQuerable<Order> GetOrdersBySellerId(int sellerId)
{
    return Order.Queryable
               .Where(x=>x.Items.Count > 0 && x.Items.First().Seller.SellerID == sellerId)();
}

Если вы хотите придерживаться простого ActiveRecordBase<T>, вы можете использовать статический метод ActiveRecordLinq.AsQueryable<T>().

public IQuerable<Order> GetOrdersBySellerId(int sellerId)
{
    return ActiveRecordLinq.AsQueryable<Order>()
               .Where(x=>x.Items.Count > 0 && x.Items.First().Seller.SellerID == sellerId)();
}

Вы пробовали это с вашими критериями поиска?(Я спрашиваю об этом, потому что, AFAIK, не все конструкции LINQ работают на NHibernate)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top