![](/img/trans.png)
[英]EF adding entity: The relationship could not be changed because one or more of the foreign-key properties is non-nullable
[英]Pocos - The relationship could not be changed because one or more of the foreign-key properties is non-nullable
我有三个表,分别是user,user_details和user_acls。 用户表是主表,另外两个是子表,用于存储与用户有关的信息。 后两个表中的外键是user_id,而user_id是用户表上的主键。
使用实体框架和pocos,我已经建立了以下类结构,并且仅对我的一个子表进行了设置,因为一旦解决了这个问题,我就可以将相同的逻辑应用于其他用户表。
用户类别
namespace myclass.Core.Domain.Customers
{
public partial class User : BaseEntity
{
private ICollection<UsersSitesAcl> _usersSitesAcls;
private ICollection<CompaniesAcl> _companiesAcls;
private ICollection<UserDetails> _userDetails;
public virtual Guid userguid { get; set; }
public virtual string first_name { get; set; }
public virtual string last_name { get; set; }
public virtual string email_address { get; set; }
public virtual System.DateTime? activated_date { get; set; }
public virtual string pwrd { get; set; }
public virtual string loginname { get; set; }
public virtual string title { get; set; }
public virtual string suffix { get; set; }
public virtual string secretquestion { get; set; }
public virtual string secretanswer { get; set; }
public virtual long? birthyear { get; set; }
public virtual string last_four_ssn { get; set; }
public virtual bool? suspended_yn { get; set; }
public virtual string account_status { get; set; }
public virtual ICollection<UsersSitesAcl> usersSitesAcls
{
get
{
var sitesAcls = new List<UsersSitesAcl>();
if (_usersSitesAcls != null)
{
var query = from usa in _usersSitesAcls
where usa.active_yn
select usa;
sitesAcls = query.ToList();
}
return sitesAcls;
}
protected set { _usersSitesAcls = value; }
}
public virtual ICollection<CompaniesAcl> companiesAcls
{
get
{
var companyAcls = new List<CompaniesAcl>();
if (_companiesAcls != null)
{
var query = from ca in _companiesAcls
where ca.active_yn
select ca;
companyAcls = query.ToList();
}
return companyAcls;
}
protected set { _companiesAcls = value; }
}
public virtual ICollection<UserDetails> userDetails
{
get
{
var userDetails = new List<UserDetails>();
if (_userDetails != null)
{
userDetails = (from ud in _userDetails where ud.active_yn select ud).ToList();
}
return userDetails;
}
set { _userDetails = value; }
}
}
}
用户详细信息类
namespace myclass.Core.Domain.Customers
{
public partial class UserDetails : BaseEntity
{
private User _updatedByUser;
public virtual long user_id { get; set; }
public virtual string primary_specialty { get; set; }
public virtual string secondary_specialty { get; set; }
public virtual string npi { get; set; }
public virtual string state_licence_number { get; set; }
public virtual string issuing_state { get; set; }
public virtual string dea_number { get; set; }
public virtual string dea_schedule1 { get; set; }
public virtual string dea_schedule2 { get; set; }
public virtual string dea_schedule3 { get; set; }
public virtual string dea_schedule4 { get; set; }
public virtual string dea_schedule5 { get; set; }
public virtual string dea_expire_date { get; set; }
public virtual string state_licence_expire_date { get; set; }
public virtual string provider_rights { get; set; }
public virtual long updated_by_user_id { get; set; }
public virtual User updatedByUser
{
get { return _updatedByUser; }
protected set
{
_updatedByUser = value;
updated_by_user_id = _updatedByUser.Id;
}
}
}
}
对于我的映射,我对用户和用户详细信息均具有以下结构
namespace myclass.Data.Mappings.Domains.Customers
{
public partial class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
this.ToTable("users");
this.HasKey(u => u.Id);
this.Property(u => u.Id).HasColumnName("user_id");
this.Property(u => u.userguid).IsRequired();
this.Property(u => u.first_name).HasMaxLength(50).IsRequired();
this.Property(u => u.last_name).HasMaxLength(50).IsRequired();
this.Property(u => u.pwrd).HasMaxLength(100).IsRequired();
this.Property(u => u.email_address).HasMaxLength(100).IsRequired();
this.Property(u => u.loginname).HasMaxLength(50).IsRequired();
this.Property(u => u.activated_date).IsOptional();
this.Property(u => u.create_date).IsRequired();
this.Property(u => u.active_yn).IsRequired();
this.Property(u => u.title).IsOptional();
this.Property(u => u.suffix).IsOptional();
this.Property(u => u.last_four_ssn).IsOptional();
this.Property(u => u.secretquestion).IsOptional();
this.Property(u => u.secretanswer).IsOptional();
this.Property(u => u.birthyear).IsOptional();
this.Property(u => u.account_status).IsOptional();
this.Property(u => u.suspended_yn).IsOptional();
this.HasMany(u => u.userDetails).WithRequired().HasForeignKey(ud => ud.user_id);
this.HasMany(u => u.usersSitesAcls).WithRequired().HasForeignKey(usa => usa.user_id);
this.HasMany(u => u.companiesAcls).WithRequired().HasForeignKey(ca => ca.user_id);
}
}
}
用户详细信息图
enter code here
namespace myclass.Data.Mappings.Domains.Customers
{
public partial class UserDetailsMap:EntityTypeConfiguration<UserDetails>
{
public UserDetailsMap()
{
this.ToTable("user_details");
this.HasKey(ud => ud.Id);
this.Property(ud => ud.Id).HasColumnName("user_detail_id");
this.Property(ud => ud.user_id).IsRequired();
this.Property(ud => ud.primary_specialty).HasColumnName("primary_speciality").IsOptional();
this.Property(ud => ud.secondary_specialty).IsOptional();
this.Property(ud => ud.npi).IsOptional();
this.Property(ud => ud.state_licence_number).HasColumnName("StateLicenseNumber").IsOptional();
this.Property(ud => ud.issuing_state).HasColumnName("IssuingState").IsOptional();
this.Property(ud => ud.dea_number).HasColumnName("DEANumber").IsOptional();
this.Property(ud => ud.dea_schedule1).HasColumnName("DEASchedule1").IsOptional();
this.Property(ud => ud.dea_schedule2).HasColumnName("DEASchedule2").IsOptional();
this.Property(ud => ud.dea_schedule3).HasColumnName("DEASchedule3").IsOptional();
this.Property(ud => ud.dea_schedule4).HasColumnName("DEASchedule4").IsOptional();
this.Property(ud => ud.dea_schedule5).HasColumnName("DEASchedule5").IsOptional();
this.Property(ud => ud.dea_expire_date).HasColumnName("DeaExpireDate").IsOptional();
this.Property(ud => ud.state_licence_expire_date).HasColumnName("StateLicenseExpireDate").IsOptional();
this.Property(ud => ud.provider_rights).HasColumnName("ProviderRights").IsOptional();
this.Property(ud => ud.active_yn).IsRequired();
this.Property(ud => ud.create_date).IsRequired();
this.Property(ud => ud.updated_by_user_id).IsRequired();
this.HasRequired(ud => ud.updatedByUser).WithMany().HasForeignKey(ud => ud.updated_by_user_id);
//
}
}
}
首先,我添加一条新记录,然后设置User类的内容(除去User_details和user_acls,它就会消失,并为用户创建记录而没有任何问题。
但是,当我尝试对user_details和user_acls执行相同操作时,我没有获得任何成功,并且尝试将user_details作为项添加到用户表的属性中而没有获得任何成功。
甚至尝试将其保存为单独的记录,我在其中存储用户记录,并检索添加的新记录的user_id。 然后为user_details和user_acls创建一个新对象,并尝试进行保存,最后得到以下消息:
我需要做些什么才能使这项工作奏效,我尝试了所有我知道的一切,但没有成功。 因此,您能提供的任何帮助将不胜感激。 谢谢。
Blockquote操作失败:由于一个或多个外键属性不可为空,因此无法更改关系。 对关系进行更改时,相关的外键属性将设置为空值。 如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。
这需要阅读很多代码,但我认为问题在于您正在修改实体状态,而实体框架并未对其进行跟踪。
尝试类似
db.Entry(currentyUser).State = EntityState.Modified;
保存更改之前。
您显示了很多代码,但我怀疑这些代码没有。例如,如何创建用户并附加用户详细信息,然后保存这些对象。
可以使用一个简单的测试
this.Ignore(ud=>ud.User)
作为用户详细信息映射的一部分。
如果这可行,则可以肯定地确定问题是与UserDetail关联的User的状态不是Unchanged。 应该发生的是,应该先保存用户,然后将其状态设置为“未更改”,然后再保存用户详细信息。
因为您没有显示附加代码并保存代码,所以我只能推测,但是我敢打赌,如果您使用的是断开连接的实体,则用户状态不会保持不变,可能已添加或某些自定义状态(例如非活动状态)。
因此,EF尝试重新创建User对象(如果状态==已添加),然后将其重新分配给UserDetails,后者通过使之前的User对象关联为空,然后附加新的对象,从而以某种方式孤立了User Details。
我仍在研究文档的确切执行方式,但是最近半个小时的经验是,父/外键对象的状态不是Unchanged。 因此,EF会将您的“用户详细信息”对象中的“用户”引用与它的DBSet中的区别。 因此为空引用。
我了解您正在同时保存一个新用户及其详细信息,但请仔细查看您的代码以了解如何执行此操作。 最有可能发生某种“用户交换”,由此您首先保存的用户实际上不是试图保存它们时附加到UserDetails的用户。 您是否在执行任何Linq ToList()类型的“ stuff”,并且无意间将引用切换到未更改的User对象。
就我而言,这是因为我在数据库中的FK对象的代码中创建了一个“存根”对象,并且在将它与我的detail对象关联之前,我忽略了它的状态为Unchanged的设置。
对不起,我的回答有点像胡扯,但我现在正在解决它。 当我更简洁地理解它时,我将更新此答案。
我发现了这一点,这与我使用autofac访问用户对象的方式有关,最终这是我的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.