NHibernate + Fluent NHibernate异常
问题:
数据库中可以存储一些搜索。每个搜索都有一组过滤器。还有角色。每个角色可能有(可为空的列)分配给它的默认搜索。此外,每个搜索对零个或多个角色可见(多对多关系)。
当我尝试访问搜索过滤器时,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 数据库列。此列存在于角色表中,但不存在于过滤器中。
问题:
是否是无效配置、Fluent NHibernate 或 NHibernate bug?
我使用的是 SQL Server 2008 R2、NHibernate 2.1.2 和 Fluent NHibernate 1.1.0.685,尽管 NHibernate 3 beta 2 中也存在这个问题。
谢谢。
更新: 这是 实际 SQL 生成的
UPDATE2:CDMDOTNET,不幸的是,同样的错误,同样的 SQL。
UPDATE3:实际异常
UPDATE4:这是一般错误的特定用例:实体将其他实体引用为 '多对多”和“多对多”关联的另一边。另一个实体引用源实体(在我的例子中为 DefaultQuery)。当访问源实体(在我的例子中是过滤器)的任何子集合(一对多)时,NH 会发疯。
UPDATE5:示例数据
UPDATE6:Fluent NHibernate 发布的 XML
Problem:
There are searches that can be stored in the DB. Each search has a collection of filters. Also there are roles. Each role may have (nullable column) a default search assigned to it. Also, each search is visible to zero or many roles (many-to-many relationship).
When I try to access the search filters, NH tries to access filters.DefaultSearchId, which doesn't exist in filters table.
DB:
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)
);
Entities:
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; }
}
Mappings:
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");
}
}
Code:
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();
}
}
ERROR:
When accessing the search.Filters property, NHibernate tries to access Filters.DefaultSearchId db column which is not supposed to be there. This column exists in Roles table but not in filters.
QUESTION:
Is it invalid configuration, Fluent NHibernate or NHibernate bug?
I'm using SQL Server 2008 R2, NHibernate 2.1.2 and Fluent NHibernate 1.1.0.685, although this issue exists in NHibernate 3 beta 2 as well.
Thank you.
UPDATE:
Here is the actual SQL generated
UPDATE2: CDMDOTNET, same error, same sql, unfortunately.
UPDATE3: Actual exception
UPDATE4: This is a particular use case of a general bug: Entity references other entities as 'many-to-many' and on the other side of 'many-to-many' assoc. the other entity references the source entity (DefaultQuery in my case). NH goes nuts when accessing any child collection (one-to-many) of a source entity (Filters in my case).
UPDATE5: Sample data
UPDATE6: XML issued by Fluent NHibernate
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
更新 SearchMap 上的 HasMany 映射以包含 KeyColumn():
HasMany(x => x.Filters).KeyColumn("SearchId").Inverse().Cascade.All().AsBag ();
Update the HasMany mapping on the SearchMap to include the KeyColumn():
HasMany(x => x.Filters).KeyColumn("SearchId").Inverse().Cascade.All().AsBag();
您没有指定过滤器包的列名称。应将其设置为 SearchId。
You didn't specify the column name for the Filters bag. It should be set to SearchId.