1

我刚刚开始在我的项目中实现ISet's 而不是IList's,因为这更好地反映了我拥有的集合。

这在创建一个表时引发了一个奇怪的错误。我得到的错误是。

无法对表“UserAddressAssignments”中的可为空列定义 PRIMARY KEY 约束。

我在用户和地址之间有多对多的关系。

public class User : BaseEntity
{
    public virtual System.Guid UserGuid { get; set; }
    public virtual string UserName { get; set; }
    public virtual Company Company { get; set; }
    public virtual Iesi.Collections.Generic.ISet<Address> UserAddressAssignments { get; set; }
}

它为查找列生成的 SQL 导致了问题,如下所示。UserId导致问题的是可以为空 的列。

create table UserAddressAssignments (
    UserAddressAssignmentId INT not null,
   AddressId INT IDENTITY NOT NULL,
   UserId INT null,
   primary key (UserId, AddressId)
)

奇怪的是,我在公司和地址之间有相同的关系,效果很好。

public class Company : BaseEntity
{
    public virtual System.Guid CompanyGuid { get; set; }
    public virtual string Name { get; set; }
    public virtual Iesi.Collections.Generic.ISet<Address> CompanyAddressAssignments { get; set; }
}

这将为查找表创建正确的 SQL。

CREATE TABLE [dbo].[CompanyAddressAssignments](
    [CompanyId] [int] NOT NULL,
    [AddressId] [int] NOT NULL,
PRIMARY KEY CLUSTERED 
(
    [CompanyId] ASC,
    [AddressId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

使用具有正确非空属性的聚集键,并且没有与用户查找列一样的第三个“CompanyAddressAssignmentId”列。

公司和用户的映射覆盖也是相同的。

public class CompanyMappingOverride : IAutoMappingOverride<Company>
{
        public void Override(FluentNHibernate.Automapping.AutoMapping<Company> mapping)
        {
            mapping.Map(x => x.Name);
            mapping.HasManyToMany(x => x.CompanyAddressAssignments).Table("CompanyAddressAssignments").Cascade.All();
        }
}

public class UserMappingOverride : IAutoMappingOverride<User>
{
    public void Override(FluentNHibernate.Automapping.AutoMapping<User> mapping)
    {
        mapping.References(x => x.Company).Cascade.All();
        mapping.HasManyToMany(x => x.UserAddressAssignments).Table("UserAddressAssignments").Cascade.All();
    }
}

有没有人对为什么这两个查找表看起来如此不同有什么建议吗?据我所知,类的结构和映射是相同的?

我现在求助于使用IList用户地址来解决这个问题。

这会发出这个创建 sql。

CREATE TABLE [dbo].[CompanyAddressAssignments](
    [CompanyId] [int] NOT NULL,
    [AddressId] [int] NOT NULL,
PRIMARY KEY CLUSTERED 
(
    [CompanyId] ASC,
    [AddressId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

关于可能导致这种差异的任何想法?

NHibernate 版本是 3.2.0.4000。

干杯

史蒂夫

4

1 回答 1

0

是的,我发现了问题所在。

我正在开发的网站已经添加了 NHibernate。为了使用代码优先/模式生成方法,我使用了一个自动化工具将现有模式转换为类,然后可以从这些类中神奇地创建模式。

我使用 NHhibernate 设计器自动生成类,然后清理实体以符合我们的标准。

http://www.devart.com/entitydeveloper/nhibernate-designer.html

当该工具为查找表生成一个类时,错误逐渐出现。所以 UserAddressAssignment 在系统中有自己的类。在创建多对多关系时,通常不需要这样做。在给定 ManyToMany 表的名称的情况下,在映射覆盖中指定了多对多的类和 ALSO,NHibernate 一定会感到困惑(不足为奇)。

我想指出,NHibernate Designer 必须使用的架构并没有完全清除任何未强制执行的关系,所以我不会责怪它在不需要时创建这个实体!

因此,当我删除下面给出的不必要的 UserAddressAssignment 类时,一切都按预期工作。

  public class UserAddressAssignment : BaseEntity
    {
        public virtual int AddressId { get; set; }
        public virtual User User { get; set; }
        public virtual Address Address { get; set; }
    }

希望这对某人有所帮助!

干杯

史蒂夫

于 2012-07-02T13:50:51.920 回答