代码之家  ›  专栏  ›  技术社区  ›  Valentin V

NHibernate+Fluent NHibernate异常

  •  3
  • Valentin V  · 技术社区  · 15 年前

    问题 :

    有些搜索可以存储在数据库中。每个搜索都有一个筛选器集合。也有角色。每个角色都可能有(可为空的列)分配给它的默认搜索。此外,每个搜索对零个或多个角色(多对多关系)可见。

    当我尝试访问搜索过滤器时,NH试图访问Field.Debug搜索器,它不存在于过滤器表中。

    数据库:

    CREATE TABLE [dbo].[Searches]
    (
        Id int identity(1,1) primary key,
        Description nvarchar(2000) not null
    );
    
    CREATE TABLE [dbo].[Filters]
    (
        Id int identity(1,1) primary key,
        Description nvarchar(2000) not null,
        SearchId int not null references Searches(Id)
    );
    
    CREATE TABLE [dbo].[Roles]
    (
        Id int identity(1,1) primary key,
        Name nvarchar(255) not null,
        DefaultSearchId int null references Searches(Id)
    );
    CREATE TABLE [dbo].[SearchesRoles]
    (
        SearchId int not null references Searches(Id),
        RoleId int not null references Roles(Id)
    );
    

    实体:

      public class Search {
            public virtual int Id { get; set; }
            public virtual string Description { get; set; }
            public virtual ICollection<Filter> Filters { get; set; }
            public virtual ICollection<Role> Roles { get; set; }
        }
    
        public class Filter {
            public virtual int Id { get; set; }
            public virtual string Description { get; set; }
            public virtual Search Search { get; set; }
        }
    
        public class Role {
            public virtual int Id { get; set; }
            public virtual string Name { get; set; }
            public virtual Search DefaultSearch { get; set; }
        }
    

    映射:

     public class SearchMap : ClassMap<Search>{
            public SearchMap() {
                Table("Searches");
                Id(x => x.Id).GeneratedBy.Identity();
                Map(x => x.Description);
                HasMany(x => x.Filters).Inverse().Cascade.All().AsBag();
                HasManyToMany(x => x.Roles).Table("SearchesRoles").ParentKeyColumn("SearchId").ChildKeyColumn("RoleId");
            }
        }
    
     public class FilterMap : ClassMap<Filter> {
            public FilterMap() {
                Table("Filters");
                Id(x => x.Id).GeneratedBy.Identity();
                Map(x => x.Description);
                References(x => x.Search).Column("SearchId");
            }
        }
     public class RoleMap : ClassMap<Role> {
            public RoleMap() {
                Table("Roles");
                Id(x => x.Id).GeneratedBy.Identity();
                Map(x => x.Name);
                References(x => x.DefaultSearch).Column("DefaultSearchId");
            }
        }
    

    代码:

    class Program {
            static void Main() {
                var sessionFactory = CreateSessionFactory();
                using (var session = sessionFactory.OpenSession()) {
                    var search = session.Get<Search>(1);
                    foreach (var filter in search.Filters) {
                        Console.WriteLine(filter);
                    }
                }
            }
    
            static ISessionFactory CreateSessionFactory(){
                string connectionString = @"server=.\sql2008; user id = sa; pwd=1; database = nhbug;";
                return Fluently.Configure()
                    .Database(MsSqlConfiguration.MsSql2008.ConnectionString(connectionString))
                    .Mappings(m=>m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly())).BuildSessionFactory();
            }
        }
    

    错误:

    当访问 搜索筛选器 属性,NHibernate试图访问 筛选器.DefaultSearchId 不应该在那里的db列。此列存在于角色表中,但不存在于筛选器中。

    问题:

    是无效配置,Fluent NHibernate还是NHibernate bug?

    我使用的是SQL Server 2008 R2、NHierBATE.2.1.2和FLUENT NHIBERATATE 1.1.0.685,尽管这个问题也存在于NHierBATE 3 beta 2中。

    谢谢您。

    更新: 这是 actual SQL 生成

    UPDATE2:CDMDOTNET,同样的错误,同样的sql,很不幸。

    更新3: Actual exception

    UPDATE4:这是一个普通bug的特殊用例:实体将其他实体引用为“多对多”,并在“多对多”关联的另一侧。其他实体引用源实体(在我的示例中为DefaultQuery)。NH在接入时失控 任何 源实体的子集合(一对多)(在我的例子中是过滤器)。

    更新5: Sample data

    更新6: XML issued by Fluent NHibernate

    2 回复  |  直到 15 年前
        1
  •  4
  •   Phill    15 年前

    更新SearchMap上的hasmanny映射以包含KeyColumn():

    HasMany(x=>x.过滤器) .KeyColumn(“搜索ID”) .Inverse().Cascade.All().AsBag();

        2
  •  0
  •   Stefan Steinegger    15 年前

    您没有为Filters包指定列名。它应该设置为SearchId。