不需要的 NHibernate 更新命令

发布于 2024-10-01 02:10:01 字数 4161 浏览 2 评论 0原文

我有以下类

public class Contact
{
    public Contact() {
        Addresses = new List<Address>();
        EmailAddresses = new List<EmailAddress>();
        PhoneNumbers = new List<PhoneNumber>();
    }
    public virtual int ContactID { get; private set; }
    public virtual Firm Firm { get; set; }
    public virtual ContactType ContactType { get; set; }
    public virtual string FullName { get; set; }
    public virtual string FiscalCode { get; set; }
    public virtual string Notes { get; set; }
    public virtual ContactRole ContactRole { get; set; }

    public virtual IList<Address> Addresses { get; private set; }
    public virtual IList<EmailAddress> EmailAddresses { get; private set; }
    public virtual IList<PhoneNumber> PhoneNumbers { get; private set; }
}

public class Address
{
    public virtual int AddressID { get; private set; }
    public virtual string StreetAddress { get; set; }
    public virtual string ZipCode { get; set; }
    public virtual string City { get; set; }
    public virtual Province Province { get; set; }
    public virtual Country Country { get; set; }
    public virtual Contact Contact { get; set; }
    public virtual AddressType AddressType { get; set; }
    public virtual bool PostalAddress { get; set; }
}

这些类已使用 FluentNHibernate 映射到数据库。这些是映射类,

public ContactMap() {
    Table( "Contacts" );
    Id( c => c.ContactID ).Column( "ContactID" ).GeneratedBy.Identity();
    References( c => c.Firm ).Column( "FirmID" );
    References( c => c.ContactType ).Column( "ContactTypeID" );
    Map( c => c.FullName );
    Map( c => c.FiscalCode );
    Map( c => c.Notes );
    References( c => c.ContactRole ).Column( "ContactRoleID" );
    HasMany( c => c.Addresses ).Cascade.SaveUpdate();
    HasMany( c => c.EmailAddresses ).Cascade.SaveUpdate();
    HasMany( c => c.PhoneNumbers ).Cascade.SaveUpdate();
}


public AddressMap() {
    Table( "Addresses" );
    Id( a => a.AddressID ).Column( "AddressID" ).GeneratedBy.Identity();
    Map( a => a.StreetAddress );
    Map( a => a.ZipCode );
    Map( a => a.City );
    References( a => a.Province ).Column( "ProvinceID" );
    References( a => a.Country ).Column( "CountryID" );
    References( a => a.Contact ).Column( "ContactID" );
    References( a => a.AddressType ).Column( "AddressTypeID" );
    Map( a => a.PostalAddress );
}

我试图使用这些类加载数据库内的大量联系人。我创建这些对象的代码可以从逻辑上解释如下,

Create a contact
For each address of this contact 
    create an address
    set the contact address
    add the address to the contact collection
Next
For each email of this contact 
    create an email
    set the contact email
    add the email to the contact collection
Next

我对所有后代集合(如电子邮件、电话号码)都没有问题,除了地址有问题。事实上,当我尝试插入至少有一个地址的联系人时,我收到以下错误

Could not insert collection: [GSLConverter.Entities.Contact.Addresses#3551][SQL: UPDATE Addresses SET AuthorID = @p0 WHERE AddressID = @p1]
Invalid column name 'AuthorID'

而不是使用 ContactID,而是使用 AuthorID。 AuthorID 从哪里来????

这些是 NHibernate 在服务器上执行的查询

INSERT INTO Addresses (StreetAddress, ZipCode, City, PostalAddress, ProvinceID, CountryID, ContactID, AddressTypeID) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7); 
select SCOPE_IDENTITY();
@p0 = 'xxx xxxxxx, 69 ', @p1 = '80142', @p2 = 'xxxxxx', @p3 = False, @p4 = 1, @p5 = 113, @p6 = 3632, @p7 = 1

UPDATE Addresses SET AuthorID = @p0 WHERE AddressID = @p1;
@p0 = 3632, @p1 = 26

@Stefan Steinegger:这是类的映射,是唯一一个引用 AuthorID 的类member

public IssueNoteMap() {
    Table( "IssueNotes" );
    Id( ino => ino.IssueNoteID ).Column( "IssueNoteID" ).GeneratedBy.Identity();
    References( ino => ino.Issue ).Column( "IssueID" );
    Map( ino => ino.NoteDate );
    Map( ino => ino.NoteTitle );
    Map( ino => ino.NoteBody );
    References( ino => ino.Author ).Column( "AuthorID" );
}

AuthorID字段是对Contact表的引用,还没有映射到Contact端(从之前的Contact映射可以看出

I have the following classes

public class Contact
{
    public Contact() {
        Addresses = new List<Address>();
        EmailAddresses = new List<EmailAddress>();
        PhoneNumbers = new List<PhoneNumber>();
    }
    public virtual int ContactID { get; private set; }
    public virtual Firm Firm { get; set; }
    public virtual ContactType ContactType { get; set; }
    public virtual string FullName { get; set; }
    public virtual string FiscalCode { get; set; }
    public virtual string Notes { get; set; }
    public virtual ContactRole ContactRole { get; set; }

    public virtual IList<Address> Addresses { get; private set; }
    public virtual IList<EmailAddress> EmailAddresses { get; private set; }
    public virtual IList<PhoneNumber> PhoneNumbers { get; private set; }
}

public class Address
{
    public virtual int AddressID { get; private set; }
    public virtual string StreetAddress { get; set; }
    public virtual string ZipCode { get; set; }
    public virtual string City { get; set; }
    public virtual Province Province { get; set; }
    public virtual Country Country { get; set; }
    public virtual Contact Contact { get; set; }
    public virtual AddressType AddressType { get; set; }
    public virtual bool PostalAddress { get; set; }
}

These classes have been mapped to the database using FluentNHibernate. These are the mapping classes

public ContactMap() {
    Table( "Contacts" );
    Id( c => c.ContactID ).Column( "ContactID" ).GeneratedBy.Identity();
    References( c => c.Firm ).Column( "FirmID" );
    References( c => c.ContactType ).Column( "ContactTypeID" );
    Map( c => c.FullName );
    Map( c => c.FiscalCode );
    Map( c => c.Notes );
    References( c => c.ContactRole ).Column( "ContactRoleID" );
    HasMany( c => c.Addresses ).Cascade.SaveUpdate();
    HasMany( c => c.EmailAddresses ).Cascade.SaveUpdate();
    HasMany( c => c.PhoneNumbers ).Cascade.SaveUpdate();
}


public AddressMap() {
    Table( "Addresses" );
    Id( a => a.AddressID ).Column( "AddressID" ).GeneratedBy.Identity();
    Map( a => a.StreetAddress );
    Map( a => a.ZipCode );
    Map( a => a.City );
    References( a => a.Province ).Column( "ProvinceID" );
    References( a => a.Country ).Column( "CountryID" );
    References( a => a.Contact ).Column( "ContactID" );
    References( a => a.AddressType ).Column( "AddressTypeID" );
    Map( a => a.PostalAddress );
}

I am trying to load a considerable amount of contacts inside the database using these classes. My code that create these object can be logically explained as follow

Create a contact
For each address of this contact 
    create an address
    set the contact address
    add the address to the contact collection
Next
For each email of this contact 
    create an email
    set the contact email
    add the email to the contact collection
Next

I have no problem with all the descendant collection like Email, PhoneNumber except that I have a problem with Address. In fact when I try to insert an contact that has at least one address I get the following error

Could not insert collection: [GSLConverter.Entities.Contact.Addresses#3551][SQL: UPDATE Addresses SET AuthorID = @p0 WHERE AddressID = @p1]
Invalid column name 'AuthorID'

Instead of using ContactID is using AuthorID. Where does that AuthorID come from????

These are the queries that NHibernate execute on the server

INSERT INTO Addresses (StreetAddress, ZipCode, City, PostalAddress, ProvinceID, CountryID, ContactID, AddressTypeID) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7); 
select SCOPE_IDENTITY();
@p0 = 'xxx xxxxxx, 69 ', @p1 = '80142', @p2 = 'xxxxxx', @p3 = False, @p4 = 1, @p5 = 113, @p6 = 3632, @p7 = 1

UPDATE Addresses SET AuthorID = @p0 WHERE AddressID = @p1;
@p0 = 3632, @p1 = 26

@Stefan Steinegger: this is the mapping of the class, the only one, that reference an AuthorID member

public IssueNoteMap() {
    Table( "IssueNotes" );
    Id( ino => ino.IssueNoteID ).Column( "IssueNoteID" ).GeneratedBy.Identity();
    References( ino => ino.Issue ).Column( "IssueID" );
    Map( ino => ino.NoteDate );
    Map( ino => ino.NoteTitle );
    Map( ino => ino.NoteBody );
    References( ino => ino.Author ).Column( "AuthorID" );
}

The AuthorID field is a reference to the Contact table that have not be still mapped on the Contact side (as you can see from the previous Contact mapping

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

§普罗旺斯的薰衣草 2024-10-08 02:10:01

IssueNote.Author 是否是 Contact 类型?如果是这样,Fluent Mapping

References( ino => ino.Author ).Column( "AuthorID" );

正在尝试更新您的“地址”表,以确保它也将 ContactId 存储在 AuthorId 你已经告诉它 IssueNote.Author 在映射到 Contact 时使用它

你已经告诉 nHibernate 这个:

alt text

当你真的想要这个时:
alt text

因此,将 IssueNoteMap 更改为以下内容,以便使用 ContactId 来映射作者并且它应该可以工作

References( ino => ino.Author ).Column( "ContactId" );

Is IssueNote.Author by any chance a type of Contact? If so, the Fluent Mapping of

References( ino => ino.Author ).Column( "AuthorID" );

is attempting to update your 'Addresses' table to ensure that it also has the ContactIdstored in the Foreign Key of AuthorId which you have told it that IssueNote.Author uses when mapping to Contacts

You have told nHibernate this:

alt text

When you really want this:
alt text

So, change the IssueNoteMap to the following so that the ContactId is used to map the Author and it should work

References( ino => ino.Author ).Column( "ContactId" );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文