Pocos—由于一个或多个外键属性不可为空,关系无法更改
本文关键字:关系 属性 于一个 Pocos | 更新日期: 2023-09-27 17:50:58
我有三个表,它们是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;
}
}
}
}
对于我的映射,我对用户和用户详细信息都有以下结构UserMap
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);
}
}
}
UserDetails地图
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创建一个新对象,并尝试保存它,最后得到以下消息:
我需要做些什么才能使这个工作,我已经尝试了我所知道的一切,但没有成功。所以你能给的任何帮助都会很感激。谢谢。
引用操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性被设置为空值。如果外键不支持空值,则必须定义一个新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。
这是很多代码阅读,但我认为问题是,你正在修改实体状态,而它没有被实体框架跟踪。
试试
db.Entry(currentyUser).State = EntityState.Modified;
您显示了大量代码,但我怀疑没有显示有问题的代码。如何创建用户并附加用户详细信息,以及如何保存这些对象。
一个简单的测试可以是使用
this.Ignore(ud=>ud.User)
作为用户详细信息映射的一部分。
如果这个工作,你可以相当肯定的问题是,与UserDetail相关联的用户有一个状态不是不变的。应该发生的是用户应该首先被保存,然后将其状态设置为Unchanged,然后用户详细信息应该被保存。
因为你不显示你的附加和保存代码,我只能推测,但我会打赌钱,用户的状态不是不变的,可能添加或一些自定义状态,如非活动,如果你使用断开连接的实体。
因此EF尝试重新创建User对象(如果state == Added),然后将其重新分配给UserDetails,这在某种程度上通过取消先前的User对象关联,然后附加新的User对象来孤儿UserDetails。
我仍然通过文档工作,确切地说这是如何发生的,但我自己的经验,就在过去的半个小时,父/外键对象有一个状态,而不是不变。EF区分了User Details对象中的User引用和它的DBSets中的User引用。因此是空引用。
我知道你同时保存了一个新用户和他们的详细信息,但是仔细看看你的代码是如何做到的。最有可能的是有某种"用户交换"正在进行,即您首先保存的用户实际上不是在尝试保存它们时附加到UserDetails的用户。你是否在做任何Linq ToList()类型"stuff"并且无意中将引用切换到非Unchanged User对象?
在我的情况下,这是因为我在db中的FK对象的代码中创建了一个"存根"对象,并且在将其与我的详细对象关联之前,我忽略了将其状态设置为Unchanged。
对不起,我的回答有点华而不实,但我现在正在努力解决它。当我理解得更清楚时,我会更新这个答案。
我弄明白了,这与我使用autofacc访问用户对象的方式有关,最终这是我自己的事情。