not-null 属性 references a null or transient value - 对Inverse和Cascade的理解
not-null property references a null or transient value - understanding of Inverse and Cascade
This is fragment of my database project, and this 是 Fluent NHibernate
自动生成的数据库片段
这些是我在上述数据库项目的 Fluent NHibernate 中的实体和映射 类。
实体:
public class BaseEntity<T> where T : BaseEntity<T> {
public virtual int Id { get; set; }
...
}
public class Person<T> : BaseEntity<T> where T : BaseEntity<T> {
public virtual string FirstName { get; set; }
public virtual string SecondName { get; set; }
public virtual string LastName { get; set; }
public virtual string PESEL { get; set; }
public virtual DateTime BirthDate { get; set; }
public virtual string City { get; set; }
public virtual string PostalCode { get; set; }
public virtual string Street { get; set; }
public virtual string HouseNr { get; set; }
public virtual string ApartmentNr { get; set; }
public virtual string PhoneNr { get; set; }
public virtual string Email { get; set; }
}
public class DrivingLicense : BaseEntity<DrivingLicense> {
#region Relations
public virtual IList<DrivingLicensePermissions> DrivingLicensePermissions { get; set; }
public virtual Student Student { get; set; }
#endregion
public virtual DateTime IssueDate { get; set; }
public virtual string DrivingLicenseNr { get; set; }
}
public class DrivingLicensePermissions : BaseEntity<DrivingLicensePermissions> {
#region Relations
public virtual DrivingLicense DrivingLicense { get; set; }
#endregion
public virtual DrivingLicenseCategory Category { get; set; }
}
映射:
class StudentMap : ClassMap<Student> {
public StudentMap() {
Id(x => x.Id);
Map(x => x.FirstName).Not.Nullable().Length(25);
Map(x => x.SecondName).Nullable().Length(25);
Map(x => x.LastName).Not.Nullable().Length(50);
Map(x => x.PESEL).Nullable().Length(11);
Map(x => x.BirthDate).Not.Nullable();
Map(x => x.City).Not.Nullable().Length(50);
Map(x => x.PostalCode).Nullable().Length(6);
Map(x => x.Street).Not.Nullable().Length(50);
Map(x => x.HouseNr).Not.Nullable().Length(10);
Map(x => x.ApartmentNr).Nullable().Length(10);
Map(x => x.PhoneNr).Nullable().Length(20);
Map(x => x.Email).Nullable().Length(100);
References(x => x.DrivingLicense).Nullable().Cascade.All();
References(x => x.User).Nullable().Cascade.All();
HasMany(x => x.Participants).Cascade.All();
}
}
class DrivingLicenseMap : ClassMap<DrivingLicense> {
public DrivingLicenseMap() {
Id(x => x.Id);
Map(x => x.IssueDate).Not.Nullable();
Map(x => x.DrivingLicenseNr).Not.Nullable().Length(20);
HasMany(x => x.DrivingLicensePermissions).Cascade.All();
References(x => x.Student).Not.Nullable();
}
}
class DrivingLicensePermissionsMap : ClassMap<DrivingLicensePermissions> {
public DrivingLicensePermissionsMap() {
Id(x => x.Id);
Map(x => x.Category).Not.Nullable();
References(x => x.DrivingLicense).Not.Nullable();
}
}
我的问题是这个异常:not-null 属性 引用了空值或瞬态值 Model.Entities.DrivingLicense.Student, 当我试图像这样
坚持学生对象时
session.Save(student);
已将 DrivingLicense 对象分配给它的 DrivingLicense 属性。
我认为这是由于错误的映射引起的 - 错误的级联或缺少逆。我尝试了很多组合,但无法正常工作。
Student table 有 DrivingLicense_id 而相反,DrivingLicense 有 Student_id 列是否正确?!
这个问题的关键是 DrivingLicense
通过 Not.Nullable()
映射引用了 Student
。这意味着当 NH 试图持久化 DrivingLicense
时,它是 Student
属性 不能是 null
.
调试代码并在 Save(student)
调用处暂停。检查对象图,查看 student
的 DrivingLicense
属性 及其 Student
属性。我的猜测是 null
.
您需要检查映射的 Not.Nullable()
方面或确保您的对象图正确 'wired',然后再坚持。
为了解决我的问题,我不得不将 Reference-to-Reference 更改为 HasOne-to-Reference。
现在看起来像这样。
实体没有改变
映射:
class StudentMap : ClassMap<Student> {
public StudentMap() {
Id(x => x.Id);
Map(x => x.FirstName).Not.Nullable().Length(25);
Map(x => x.SecondName).Nullable().Length(25);
Map(x => x.LastName).Not.Nullable().Length(50);
Map(x => x.PESEL).Nullable().Length(11);
Map(x => x.BirthDate).Not.Nullable();
Map(x => x.City).Not.Nullable().Length(50);
Map(x => x.PostalCode).Nullable().Length(6);
Map(x => x.Street).Not.Nullable().Length(50);
Map(x => x.HouseNr).Not.Nullable().Length(10);
Map(x => x.ApartmentNr).Nullable().Length(10);
Map(x => x.PhoneNr).Nullable().Length(20);
Map(x => x.Email).Nullable().Length(100);
HasOne(x => x.DrivingLicense).PropertyRef(x => x.Student).Cascade.All();
References(x => x.User).Unique().Not.Nullable();
HasMany(x => x.Participants).Cascade.All();
}
}
class DrivingLicenseMap : ClassMap<DrivingLicense> {
public DrivingLicenseMap() {
Id(x => x.Id);
Map(x => x.IssueDate).Not.Nullable();
Map(x => x.DrivingLicenseNr).Not.Nullable().Length(20);
HasMany(x => x.DrivingLicensePermissions).Cascade.All();
References(x => x.Student).Unique().Not.Nullable();
}
}
class DrivingLicensePermissionsMap : ClassMap<DrivingLicensePermissions> {
public DrivingLicensePermissionsMap() {
Id(x => x.Id);
Map(x => x.Category).Not.Nullable();
References(x => x.DrivingLicense).Nullable();
}
}
感谢这一变化,循环引用消失了。 see it here
Students table 中没有 DrivingLicense_id,现在我可以像以前一样保存 Student 实体和 DrivingLicense,它是权限。
session.Save(student);
This is fragment of my database project, and this 是 Fluent NHibernate
自动生成的数据库片段这些是我在上述数据库项目的 Fluent NHibernate 中的实体和映射 类。
实体:
public class BaseEntity<T> where T : BaseEntity<T> {
public virtual int Id { get; set; }
...
}
public class Person<T> : BaseEntity<T> where T : BaseEntity<T> {
public virtual string FirstName { get; set; }
public virtual string SecondName { get; set; }
public virtual string LastName { get; set; }
public virtual string PESEL { get; set; }
public virtual DateTime BirthDate { get; set; }
public virtual string City { get; set; }
public virtual string PostalCode { get; set; }
public virtual string Street { get; set; }
public virtual string HouseNr { get; set; }
public virtual string ApartmentNr { get; set; }
public virtual string PhoneNr { get; set; }
public virtual string Email { get; set; }
}
public class DrivingLicense : BaseEntity<DrivingLicense> {
#region Relations
public virtual IList<DrivingLicensePermissions> DrivingLicensePermissions { get; set; }
public virtual Student Student { get; set; }
#endregion
public virtual DateTime IssueDate { get; set; }
public virtual string DrivingLicenseNr { get; set; }
}
public class DrivingLicensePermissions : BaseEntity<DrivingLicensePermissions> {
#region Relations
public virtual DrivingLicense DrivingLicense { get; set; }
#endregion
public virtual DrivingLicenseCategory Category { get; set; }
}
映射:
class StudentMap : ClassMap<Student> {
public StudentMap() {
Id(x => x.Id);
Map(x => x.FirstName).Not.Nullable().Length(25);
Map(x => x.SecondName).Nullable().Length(25);
Map(x => x.LastName).Not.Nullable().Length(50);
Map(x => x.PESEL).Nullable().Length(11);
Map(x => x.BirthDate).Not.Nullable();
Map(x => x.City).Not.Nullable().Length(50);
Map(x => x.PostalCode).Nullable().Length(6);
Map(x => x.Street).Not.Nullable().Length(50);
Map(x => x.HouseNr).Not.Nullable().Length(10);
Map(x => x.ApartmentNr).Nullable().Length(10);
Map(x => x.PhoneNr).Nullable().Length(20);
Map(x => x.Email).Nullable().Length(100);
References(x => x.DrivingLicense).Nullable().Cascade.All();
References(x => x.User).Nullable().Cascade.All();
HasMany(x => x.Participants).Cascade.All();
}
}
class DrivingLicenseMap : ClassMap<DrivingLicense> {
public DrivingLicenseMap() {
Id(x => x.Id);
Map(x => x.IssueDate).Not.Nullable();
Map(x => x.DrivingLicenseNr).Not.Nullable().Length(20);
HasMany(x => x.DrivingLicensePermissions).Cascade.All();
References(x => x.Student).Not.Nullable();
}
}
class DrivingLicensePermissionsMap : ClassMap<DrivingLicensePermissions> {
public DrivingLicensePermissionsMap() {
Id(x => x.Id);
Map(x => x.Category).Not.Nullable();
References(x => x.DrivingLicense).Not.Nullable();
}
}
我的问题是这个异常:not-null 属性 引用了空值或瞬态值 Model.Entities.DrivingLicense.Student, 当我试图像这样
坚持学生对象时session.Save(student);
已将 DrivingLicense 对象分配给它的 DrivingLicense 属性。
我认为这是由于错误的映射引起的 - 错误的级联或缺少逆。我尝试了很多组合,但无法正常工作。 Student table 有 DrivingLicense_id 而相反,DrivingLicense 有 Student_id 列是否正确?!
这个问题的关键是 DrivingLicense
通过 Not.Nullable()
映射引用了 Student
。这意味着当 NH 试图持久化 DrivingLicense
时,它是 Student
属性 不能是 null
.
调试代码并在 Save(student)
调用处暂停。检查对象图,查看 student
的 DrivingLicense
属性 及其 Student
属性。我的猜测是 null
.
您需要检查映射的 Not.Nullable()
方面或确保您的对象图正确 'wired',然后再坚持。
为了解决我的问题,我不得不将 Reference-to-Reference 更改为 HasOne-to-Reference。
现在看起来像这样。
实体没有改变
映射:
class StudentMap : ClassMap<Student> {
public StudentMap() {
Id(x => x.Id);
Map(x => x.FirstName).Not.Nullable().Length(25);
Map(x => x.SecondName).Nullable().Length(25);
Map(x => x.LastName).Not.Nullable().Length(50);
Map(x => x.PESEL).Nullable().Length(11);
Map(x => x.BirthDate).Not.Nullable();
Map(x => x.City).Not.Nullable().Length(50);
Map(x => x.PostalCode).Nullable().Length(6);
Map(x => x.Street).Not.Nullable().Length(50);
Map(x => x.HouseNr).Not.Nullable().Length(10);
Map(x => x.ApartmentNr).Nullable().Length(10);
Map(x => x.PhoneNr).Nullable().Length(20);
Map(x => x.Email).Nullable().Length(100);
HasOne(x => x.DrivingLicense).PropertyRef(x => x.Student).Cascade.All();
References(x => x.User).Unique().Not.Nullable();
HasMany(x => x.Participants).Cascade.All();
}
}
class DrivingLicenseMap : ClassMap<DrivingLicense> {
public DrivingLicenseMap() {
Id(x => x.Id);
Map(x => x.IssueDate).Not.Nullable();
Map(x => x.DrivingLicenseNr).Not.Nullable().Length(20);
HasMany(x => x.DrivingLicensePermissions).Cascade.All();
References(x => x.Student).Unique().Not.Nullable();
}
}
class DrivingLicensePermissionsMap : ClassMap<DrivingLicensePermissions> {
public DrivingLicensePermissionsMap() {
Id(x => x.Id);
Map(x => x.Category).Not.Nullable();
References(x => x.DrivingLicense).Nullable();
}
}
感谢这一变化,循环引用消失了。 see it here
Students table 中没有 DrivingLicense_id,现在我可以像以前一样保存 Student 实体和 DrivingLicense,它是权限。
session.Save(student);