简体   繁体   English

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

[英]Pocos - The relationship could not be changed because one or more of the foreign-key properties is non-nullable

I have three tables, and they are user, user_details and user_acls. 我有三个表,分别是user,user_details和user_acls。 The user table is master table, and the other two are children tables that store information related to the user. 用户表是主表,另外两个是子表,用于存储与用户有关的信息。 The foreign key in the latter two tables is user_id, and user_id is the primary key on the user table. 后两个表中的外键是user_id,而user_id是用户表上的主键。

Using entity framework and pocos I have set up the following class structure, and I will only do it for one of my child tables, as once I have this resolved I should be able to apply the same logic to my other user table. 使用实体框架和pocos,我已经建立了以下类结构,并且仅对我的一个子表进行了设置,因为一旦解决了这个问题,我就可以将相同的逻辑应用于其他用户表。

User Class 用户类别

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; }
        }

    }
}

User Details Class 用户详细信息类

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;
            }
        }
    }
}

For my mapping I have the following structure for both the user and user details 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 Map 用户详细信息图

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);
        //
}
    }
}

First of I am adding a new record, and I set the contents of the User class (bar the User_details and user_acls, and it goes out and creates the record for the user without any issues. 首先,我添加一条新记录,然后设置User类的内容(除去User_details和user_acls,它就会消失,并为用户创建记录而没有任何问题。

However, when I try to do the same for the user_details and user_acls, I have not had any success, and have tried to adding the user_details as item to the property on the user table without any success. 但是,当我尝试对user_details和user_acls执行相同操作时,我没有获得任何成功,并且尝试将user_details作为项添加到用户表的属性中而没有获得任何成功。

And have even tried saving it out as a separate record, where I store the user record, retrieve the user_id of the new record added. 甚至尝试将其保存为单独的记录,我在其中存储用户记录,并检索添加的新记录的user_id。 Then create a new object for user_details and user_acls, and try to a save on that and I end up with the following message: 然后为user_details和user_acls创建一个新对象,并尝试进行保存,最后得到以下消息:

What do I need to do to make this work, I have tried everything I know and no success. 我需要做些什么才能使这项工作奏效,我尝试了所有我知道的一切,但没有成功。 So any help ye can give would be appreciated. 因此,您能提供的任何帮助将不胜感激。 Thanks. 谢谢。

Blockquote The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. Blockquote操作失败:由于一个或多个外键属性不可为空,因此无法更改关系。 When a change is made to a relationship, the related foreign-key property is set to a null value. 对关系进行更改时,相关的外键属性将设置为空值。 If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted. 如果外键不支持空值,则必须定义新的关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

That's a lot of code to read but I think the issue is that you're modifying the entity state while it's not being tracked by the entity framework. 这需要阅读很多代码,但我认为问题在于您正在修改实体状态,而实体框架并未对其进行跟踪。

Try something like 尝试类似

     db.Entry(currentyUser).State = EntityState.Modified;

before saving changes. 保存更改之前。

You show a lot of code but not, I suspect, the code in question.ie how you create a user and attach user detail and then how you save those objects. 您显示了很多代码,但我怀疑这些代码没有。例如,如何创建用户并附加用户详细信息,然后保存这些对象。

A simple test can be to use 可以使用一个简单的测试

this.Ignore(ud=>ud.User) 

as part of your user detail mapping. 作为用户详细信息映射的一部分。

If this works you can be fairly certain the issue is that the User associated with the UserDetail has a state other than Unchanged. 如果这可行,则可以肯定地确定问题是与UserDetail关联的User的状态不是Unchanged。 What should be happening is that the User should be getting saved first and then having its state set to Unchanged and then the User Details should be getting saved. 应该发生的是,应该先保存用户,然后将其状态设置为“未更改”,然后再保存用户详细信息。

Because you dont show your attach and save code I can only speculate but I would bet money that the state of User is not Unchanged, probably Added or some custom state like Inactive if you are using disconnected entities. 因为您没有显示附加代码并保存代码,所以我只能推测,但是我敢打赌,如果您使用的是断开连接的实体,则用户状态不会保持不变,可能已添加或某些自定义状态(例如非活动状态)。

Therefore EF tries to recreate the User object ( if state == Added) and then reassign it to the UserDetails which somehow orphans the User Details by nulling the previous User object association and then attaching the new. 因此,EF尝试重新创建User对象(如果状态==已添加),然后将其重新分配给UserDetails,后者通过使之前的User对象关联为空,然后附加新的对象,从而以某种方式孤立了User Details。

I'm still working through the docs on exactly how this happens but my own experience just this last half hour has been that the parent / foreign key object had a state other than Unchanged. 我仍在研究文档的确切执行方式,但是最近半个小时的经验是,父/外键对象的状态不是Unchanged。 So EF is differentiating the reference of User in your User Details object from what it has in it's DBSets. 因此,EF会将您的“用户详细信息”对象中的“用户”引用与它的DBSet中的区别。 Thus the null reference. 因此为空引用。

I understand you are saving a new User and their details at the same time but look carefully at your code as to how you do that. 我了解您正在同时保存一个新用户及其详细信息,但请仔细查看您的代码以了解如何执行此操作。 Most likely there is some kind of "User swap" going on whereby the User you save first is not actually the User that's attached to UserDetails when trying to save them. 最有可能发生某种“用户交换”,由此您首先保存的用户实际上不是试图保存它们时附加到UserDetails的用户。 Are you doing any Linq ToList() type "stuff" and inadvertently switching references to an non Unchanged User object. 您是否在执行任何Linq ToList()类型的“ stuff”,并且无意间将引用切换到未更改的User对象。

In my case it was because I was creating a "stub" object in code of an FK object in the db and I overlooked settings it's state to Unchanged before associating it with my detail object. 就我而言,这是因为我在数据库中的FK对象的代码中创建了一个“存根”对象,并且在将它与我的detail对象关联之前,我忽略了它的状态为Unchanged的设置。

Sorry that my answer is a bit of a waffle but Im just working it through it now. 对不起,我的回答有点像胡扯,但我现在正在解决它。 When I understand it more consisely I will update this answer. 当我更简洁地理解它时,我将更新此答案。

我发现了这一点,这与我使用autofac访问用户对象的方式有关,最终这是我的事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 EF添加实体:由于一个或多个外键属性不可为空,因此无法更改关系 - EF adding entity: The relationship could not be changed because one or more of the foreign-key properties is non-nullable 实体框架5无法更改该关系,因为一个或多个外键属性不可为空 - Entity Framework 5 The relationship could not be changed because one or more of the foreign-key properties is non-nullable 由于一个或多个外键属性不可为空,因此无法更改该关系 - The relationship could not be changed because one or more of the foreign-key properties is non-nullable 操作失败:由于一个或多个外键属性不可为空,因此无法更改该关系asdf - The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable, asdf EF 6.1.1-无法更改关系,因为一个或多个外键属性不可为空 - EF 6.1.1 - The relationship could not be changed because one or more of the foreign-key properties is non-nullable 实体框架无法更改关系,因为一个或多个外键属性不可为空 - Entity Framework The relationship could not be changed because one or more of the foreign-key properties is non-nullable EF 6:插入多个-无法更改关系,因为一个或多个外键属性不可为空 - EF 6: inserting multiple - The relationship could not be changed because one or more of the foreign-key properties is non-nullable 操作失败:无法更改关系,因为一个或多个外键属性不可为空 - The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable 由于一个或多个外键属性不可为空,因此无法更改该关系 - The relationship could not be changed because one or more of the foreign-key properties is non-nullable 尝试更新实体框架中的记录无法更改关系,因为一个或多个外键属性不可为空 - Trying to update record in entity framework The relationship could not be changed because one or more of the foreign-key properties is non-nullable
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM