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

时间:2014-03-19 23:17:54

标签: c# entity-framework-5 poco

我有三个表,它们是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);
        }
    }
}

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

首先我要添加一条新记录,然后设置User类的内容(禁止User_details和user_acls,它会熄灭并为用户创建记录而不会出现任何问题。

但是,当我尝试对user_details和user_acls执行相同操作时,我没有取得任何成功,并尝试将user_details作为项添加到用户表的属性中,但没有成功。

甚至尝试将其保存为单独的记录,我存储用户记录,检索添加的新记录的user_id。然后为user_details和user_acls创建一个新对象,并尝试保存,最后得到以下消息:

我需要做些什么来完成这项工作,我已经尝试了所有我知道但没有成功的事情。所以你们给予的任何帮助都会受到赞赏。感谢。

  

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

3 个答案:

答案 0 :(得分:0)

需要阅读的代码很多,但我认为问题是您在实体框架未跟踪实体状态时会修改实体状态。

尝试类似

的内容
     db.Entry(currentyUser).State = EntityState.Modified;

保存更改之前。

答案 1 :(得分:0)

你展示了很多代码,但我怀疑,代码没有。问题。如何创建用户并附加用户详细信息,以及如何保存这些对象。

一个简单的测试可以使用

this.Ignore(ud=>ud.User) 

作为用户详细信息映射的一部分。

如果这样可行,您可以确定问题是与UserDetail关联的用户的状态不是Unchanged。应该发生的事情是用户应该首先保存,然后将其状态设置为Unchanged,然后应该保存用户详细信息。

因为你没有显示你的附加和保存代码我只能推测,但我敢打赌用户的状态不是不变的钱,可能是添加或一些自定义状态如非活动如果你使用断开连接的实体。

因此,EF会尝试重新创建User对象(如果state == Added),然后将其重新分配给UserDetails,它通过将以前的User对象关联归零然后附加新的来以某种方式孤立用户详细信息。

我仍然正在研究文档究竟是如何发生这种情况但是我自己在最后半小时的经历是父/外键对象的状态不是Unchanged。因此,EF将用户详细信息对象中的用户参考与其在DBSets中的参考区分开来。因此空引用。

我知道您正在同时保存新用户及其详细信息,但请仔细查看您的代码,了解如何执行此操作。最有可能是某种用户交换&#34;继续,首先保存的用户实际上并不是用户在尝试保存时附加到UserDetails的用户。你在做任何Linq ToList()类型&#34;东西&#34;并且无意中将引用切换到非Unchanged User对象。

在我的情况下,这是因为我正在创建一个&#34; stub&#34;数据库中的FK对象的代码中的对象,我忽略了设置,它将状态设置为Unchanged,然后将其与我的详细对象关联起来。

很抱歉,我的回答有点夸张,但我现在正在努力解决这个问题。当我更明白地理解它时,我会更新这个答案。

答案 2 :(得分:0)

我想出了这个,它与我使用autofac访问用户对象的方式有关,最后它是我的结果。