簡體   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