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创建一个新对象,并尝试保存它,最后得到以下消息:

我需要做些什么才能使这个工作,我已经尝试了我所知道的一切,但没有成功。所以你能给的任何帮助都会很感激。谢谢。

引用操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性被设置为空值。如果外键不支持空值,则必须定义一个新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

Pocos—由于一个或多个外键属性不可为空,关系无法更改

这是很多代码阅读,但我认为问题是,你正在修改实体状态,而它没有被实体框架跟踪。

试试

     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访问用户对象的方式有关,最终这是我自己的事情。