不需要的 NHibernate 更新命令
我有以下类
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
IssueNote.Author
是否是Contact
类型?如果是这样,Fluent Mapping
正在尝试更新您的“地址”表,以确保它也将
ContactId
存储在AuthorId 你已经告诉它
IssueNote.Author
在映射到Contact
时使用它你已经告诉 nHibernate 这个:
当你真的想要这个时:
因此,将 IssueNoteMap 更改为以下内容,以便使用 ContactId 来映射作者并且它应该可以工作
Is
IssueNote.Author
by any chance a type ofContact
? If so, theFluent Mapping
ofis attempting to update your 'Addresses' table to ensure that it also has the
ContactId
stored in the Foreign Key ofAuthorId
which you have told it thatIssueNote.Author
uses when mapping toContact
sYou have told nHibernate this:
When you really want this:
So, change the IssueNoteMap to the following so that the ContactId is used to map the Author and it should work