FluentNHibernate,子集合依赖

时间:2011-01-31 17:30:08

标签: c# .net nhibernate fluent-nhibernate nhibernate-mapping

我尝试制作一个更有用的FluentNHibernate tutorial示例,但我对从存储库请求时对象具有哪种类型的依赖项感到困惑。基本上我希望对象

  1. 双向;所以我可以遍历/减少对象层次结构
  2. 解耦来自NHibernate,存储库,会话(所有我还不太了解的事情)
  3. 无延迟负载(因为我不需要它,而且它可以帮助我(2),我认为)
  4. 我很难理解 if,how和why 我工作的例子实际上是否满足这些要点。但是当我请求List并在代码中中断时,我看到子集合列表属于以下类型:

    NHibernate.Collection.Generic.PersistentGenericBag<Store>
    

    ..这对我来说有点太复杂了..

    所以,我的具体问题是:

    1. 完全解耦需要进行哪些更改?,即检索简单列表的对象层次结构? (主要概念,必须改变的类别等)
    2. 我相信这就是我所需要的,因为;我为单个用户编写单物理层应用程序,不需要“撤消逻辑”。我只是希望事情尽可能松散,因为当我使用“推/拉”方法时,我觉得它提供了更可靠的代码。

      产品类:

      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 个答案:

答案 0 :(得分:1)

我不太明白为什么你想要进一步解耦。 您公开的公共接口已经是IList的形式。您可以将IList公开为IEnumerable。这将使它成为一个只读集合。 (您必须将它与FluentNHibernate映射到字段而不是属性)

PersistentGenericBag用于更改跟踪。 例如,NHibernate如何知道添加实体或从列表中删除实体?

编辑:转换延迟加载被认为是过早优化。如果必须,最好将其从映射中删除并在存储库中启用它。