NHibernate + Fluent NHibernate 异常

Posted

技术标签:

【中文标题】NHibernate + Fluent NHibernate 异常【英文标题】:NHibernate + Fluent NHibernate exception 【发布时间】:2010-11-15 13:08:35 【问题描述】:

问题

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

当我尝试访问搜索过滤器时,NH 尝试访问 filters.DefaultSearchId,它在过滤器表中不存在。

数据库:

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();
        
    

错误:

当访问 search.Filters 属性时,NHibernate 会尝试访问不应该存在的 Filters.DefaultSearchId db 列。此列存在于 Roles 表中,但不存在于过滤器中。

问题:

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

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

谢谢。

更新: 这是生成的actual SQL

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

更新3:Actual exception

UPDATE4:这是一个一般错误的特殊用例:实体将其他实体引用为“多对多”,而在“多对多”关联的另一侧。另一个实体引用源实体(在我的例子中为 DefaultQuery)。 NH 在访问源实体的 any 子集合(一对多)时会发疯(在我的例子中是过滤器)。

UPDATE5:Sample data

UPDATE6:XML issued by Fluent NHibernate

【问题讨论】:

你能把生成的 SQL 查询也发布一下吗? 出于好奇,将 ".Cascade.None( )" 添加到 References(x => x.DefaultSearch).Column("DefaultSearchId");和 HasMany(x => x.Filters).Inverse().Cascade.All().AsBag() 上的“.AsSet()”而不是“.AsBag()”; 你能发布实际的错误吗? 我在使用 NH3 Beta 2 运行您的代码时遇到另一个错误。“SELECT filters0_.Search_id as Search4_1_”试图获取“Search_id”?!? 啊,您可以像我上一条评论一样通过在 HasMany 上添加 KeyColumn 来解决这个问题。一定是 Fluent 对角色映射感到困惑。奇怪。 【参考方案1】:

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

HasMany(x => x.Filters).KeyColumn("SearchId").Inverse().Cascade.All().AsBag();

【讨论】:

SO说我可能会在5小时内奖励赏金,所以会等到那时。 没问题,调试很有趣。【参考方案2】:

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

【讨论】:

以上是关于NHibernate + Fluent NHibernate 异常的主要内容,如果未能解决你的问题,请参考以下文章

用 Fluent Nhibernate 定义 NHibernate 过滤器的语法?

Fluent NHibernate and Mysql,SQLite

Fluent NHibernate - NHibernate.QueryException:无法解析属性

Fluent Nhibernate and Stored Procedures

Fluent 映射和 NHibernate Xml 配置

Castle Windsor 3 + Fluent NHibernate + Castle.NHibernate.Integration