繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM