【问题标题】:NHibernate incorrectly creating ManyToMany table - Cannot define PRIMARY KEY constraint on nullable column errorNHibernate 错误地创建 ManyToMany 表 - 无法在可为空的列错误上定义 PRIMARY KEY 约束
【发布时间】:2012-07-02 21:50:51
【问题描述】:

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

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

无法在表“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”列,就像用户查找列一样。

Company 和 User 的映射覆盖也是相同的。

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。

干杯

史蒂夫

【问题讨论】:

    标签: sql-server nhibernate fluent-nhibernate


    【解决方案1】:

    是的,我已经找到问题所在了。

    我正在开发的网站已经添加了 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; }
        }
    

    希望这对某人有所帮助!

    干杯

    史蒂夫

    【讨论】:

      猜你喜欢
      • 2021-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-17
      • 2020-03-13
      • 1970-01-01
      相关资源
      最近更新 更多