C# FluentNHibernate,子集合依赖项

C# FluentNHibernate,子集合依赖项,c#,.net,nhibernate,fluent-nhibernate,nhibernate-mapping,C#,.net,Nhibernate,Fluent Nhibernate,Nhibernate Mapping,我试图制作一个更有用的示例,但我不清楚当从存储库请求时,对象具有什么类型的依赖关系。基本上我希望对象是: 双向;所以我可以遍历上/下对象层次 与NHibernate、存储库、会话解耦(所有我还不太了解的事情) 没有懒散的负载(因为我不需要它,而且它对我(2)有帮助,我想) 我很难理解我所研究的示例是否满足这些要点,如何满足这些要点,以及为什么满足这些要点。但当我请求列表并中断代码时,我看到子集合列表属于以下类型: NHibernate.Collection.Generic.PersistentG

我试图制作一个更有用的示例,但我不清楚当从存储库请求时,对象具有什么类型的依赖关系。基本上我希望对象是

  • 双向;所以我可以遍历上/下对象层次
  • 与NHibernate、存储库、会话解耦(所有我还不太了解的事情)
  • 没有懒散的负载(因为我不需要它,而且它对我(2)有帮助,我想)
  • 我很难理解我所研究的示例是否满足这些要点,如何满足这些要点,以及为什么满足这些要点。但当我请求列表并中断代码时,我看到子集合列表属于以下类型:

    NHibernate.Collection.Generic.PersistentGenericBag<Store>
    
    映射:

    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 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;
            } 
        }
    
    公共类ProductMap:ClassMap
    {
    公共产品地图()
    {
    Id(x=>x.Id).GeneratedBy.Identity();
    Map(x=>x.Name).Length(20);
    地图(x=>x.Price).CustomSqlType(“十进制”).Precision(9).Scale(2);
    HasManyToMany(x=>x.StoresStockedIn)
    .Cascade.All()
    .Inverse()
    .表格(“存储产品”);
    }
    }
    公共类存储映射:类映射
    {
    公共存储地图()
    {
    Id(x=>x.Id);
    Map(x=>x.Name);
    HasMany(x=>x.Staff)//1:m
    .Inverse()//关系的另一端负责保存
    .Cascade.All();//告诉NH级联事件
    HasManyToMany(x=>x.Products).Cascade.All()
    .Table(“StoreProduct”);//设置m:m连接表
    //..仅双向m:m需要
    }
    }
    公共类EmployeeMap:ClassMap
    {
    公共雇员地图()
    {
    Id(x=>x.Id);//默认情况下,生成一个int-Id作为标识
    Map(x=>x.FirstName);
    Map(x=>x.LastName);
    引用(x=>x.Store).Cascade.None().Not.LazyLoad();
    }
    }
    
    存储库:

    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 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;
            } 
        }
    
    public ICollection GetAll()
    {
    使用(ISession session=FNH_Manager.OpenSession())
    {
    var products=session.CreateCriteria(typeof(Product)).List();
    退货产品;
    } 
    }
    
    我不太明白为什么要进一步解耦。 您正在公开的公共接口已经是IList的形式。您可以将IList公开为IEnumerable。这将使它成为一个只读集合。(必须使用FluentNHibernate将其映射到字段而不是属性)

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


    编辑:延迟加载的转向被认为是过早的优化。如果有必要,最好不要在映射中使用它,而是在存储库中启用它。

    关于changetracking,我假设要么需要保存我请求保存的完整对象,要么需要在每个表中引入IsChanged和IsDeleted属性(?)实际上,这些是我想了解的类型;需要什么。正如我正在努力学习的,我没有数据库/存储库等方面的经验。关闭懒散加载对我来说非常重要,因为我使用的应用程序需要零延迟。所以这个例子可能看起来不合适,但这个例子只是为了学习。