FluentNHibernate, зависимости дочерней коллекции - PullRequest
0 голосов
/ 31 января 2011

Я пытаюсь создать более полезный образец учебника FluentNHibernate , но я не совсем понимаю, какой тип зависимостей у объектов при запросе из репозитория.В основном Я хочу, чтобы объекты были :

  1. Двунаправленный ;поэтому я могу перемещаться вверх / вниз по иерархии объектов
  2. Отсоединено от NHibernate, сессий, сессий (все то, что я пока не слишком хорошо понимаю)
  3. Не ленивая нагрузка (так как мне это не нужно, и я думаю, это помогает мне (2))

Мне немного трудно понять , если,как и почему пример, над которым я работаю, на самом деле удовлетворяет этим требованиям или нет.Но когда я запрашиваю List и делаю перерыв в коде, я вижу, что списки дочерних коллекций имеют тип:

NHibernate.Collection.Generic.PersistentGenericBag<Store>

.., который слишком сложен для моей головы ..

Итак, мой конкретный вопрос таков:

  1. Какие изменения необходимы для полной развязки ?, Т.е. для получения иерархий объектов простых списков?(Какие основные понятия, в каких классах и т. Д. Это необходимо изменить)

Я считаю, что это то, что мне нужно, так как;Я пишу одноуровневое приложение для одного пользователя без требования «отменить логику».Я просто хочу, чтобы все было как можно более свободным, так как я чувствую, что он дает гораздо более надежный код, когда я использую своего рода «push / pull» подход.

Класс продукта:

public   class Product
{
    public int Id { get; private set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public IList<Store> StoresStockedIn { get; private set; }

    public Product()
    {
        StoresStockedIn = new List<Store>();

    }
}

Класс магазина:

public class Store
{
    public int Id { get; private set; }
    public string Name { get; set; }
    public IList<Product> Products { get; set; }
    public IList<Employee> Staff { get; set; }

    public Store()
    {
        Products = new List<Product>();
        Staff = new List<Employee>();
    }


    // AddProduct & AddEmployee is required. "NH needs you to set both sides before
    // it will save correctly" ??

    public void AddProduct(Product product)
    {
        product.StoresStockedIn.Add(this);
        Products.Add(product);
    }

    public void AddEmployee(Employee employee)
    {
        employee.Store = this;
        Staff.Add(employee);
    }
}

Класс работника:

   public class Employee
{
    public int Id { get;  private set; }
    public string FirstName { get;  set; }
    public string LastName { get;  set; }
    public Store Store { get; set; }
}

Отображение:

public class ProductMap : ClassMap<Product>
{
    public ProductMap() 
    {
        Id(x => x.Id).GeneratedBy.Identity();
        Map(x => x.Name).Length(20);
        Map(x => x.Price).CustomSqlType("decimal").Precision(9).Scale(2);
        HasManyToMany(x => x.StoresStockedIn)
        .Cascade.All()
        .Inverse()
        .Table("StoreProduct");
     }
}

public class StoreMap : ClassMap<Store>
{
    public StoreMap()
    {
        Id(x => x.Id);
        Map(x =>  x.Name);
        HasMany(x => x.Staff)    // 1:m
            .Inverse()           // other end of relation is responsible for saving
            .Cascade.All();     // Tells NH to cascade events
        HasManyToMany(x => x.Products).Cascade.All()
            .Table("StoreProduct");   // Set m:m join table
        // ..only required for bi-directional m:m
    }
}

public class EmployeeMap : ClassMap<Employee> 
{
    public EmployeeMap()
    {
        Id(x => x.Id);  // By default an int Id is generated as identity
        Map(x => x.FirstName);
        Map(x => x.LastName);
        References(x => x.Store).Cascade.None().Not.LazyLoad();    
    }
}

Репозиторий:

    public ICollection<Product> GetAll()
    {
        using (ISession session = FNH_Manager.OpenSession())
        {
            var products = session.CreateCriteria(typeof(Product)).List<Product>();

            return products;
        } 
    }

1 Ответ

1 голос
/ 31 января 2011

Я не совсем понимаю, почему вы хотели бы отделить дальше. Публичный интерфейс, который вы выставляете, уже имеет форму IList. Вы можете выставить этот IList как IEnumerable. Это сделало бы коллекцию только для чтения. (вам нужно сопоставить его с FluentNHibernate с полем вместо свойства)

PersistentGenericBag предназначен для отслеживания изменений. Например, как NHibernate узнает, когда объект был добавлен или удален из списка?

edit: Превращение ленивой загрузки считается преждевременной оптимизацией. Лучше оставить его вне сопоставлений и включить его в своих репозиториях, если потребуется.

...