EF6 数据库优先:违反多重约束。关系“...”的角色“...”具有多重性 1 或 0..1

EF6 Database-First: Multiplicity constraint violated. The role '...' of the relationship '...' has multiplicity 1 or 0..1

我遇到错误

Multiplicity constraint violated. The role 'CollectionSite_CollectionSiteOption_Target' of the relationship 'DatabaseRefreshRecovery.Data.CollectionSite_CollectionSiteOption' has multiplicity 1 or 0..1.

我不知道是什么原因。

从我发现的 Google 结果来看,这个错误似乎与更新分离的实体有关。我什么都不做。从数据库中检索数据时出现此错误。

我在桌面应用程序中使用 EF6。这些实体是一对一的关系,其中 SiteID 在父 table (CollectionSite) 中用作主键,在子 table (CollectionSiteOption).

下面是我的 classes,导致错误的代码行,以及 classes 的上下文部分。有没有人看到我可能遗漏的任何内容或知道可能发生了什么?

CollectionSite class:

namespace DatabaseRefreshRecovery.Models
{
    public class CollectionSite
    {
        public CollectionSite()
        {
            AlereSites = new List<AlereSite>();
            AtnSites = new List<AtnSite>();
            ClientCollSites = new List<ClientCollSite>();
            CollectionSiteCarriers = new List<CollectionSiteCarrier>();
            //CollectionSiteExtra = new CollectionSiteExtra();
            CollectionSiteGroups = new List<CollectionSiteGroups>();
            ClinicAttributesAssignments = new List<ClinicAttributesAssignment>();
            CollectionSiteMultiples = new List<CollectionSiteMultiple>();
            CollectionSiteOption = new CollectionSiteOption();
            CollectionSitePanels = new List<CollectionSitePanel>();
            CrlSites = new List<CrlSite>();
            CsAddresses = new List<CsAddress>();
            //HoursOfOperation = new HoursOfOperation();
            ReimbursementHistories = new List<ReimbursementHistory>();
            SiteDynamicServices = new List<SiteDynamicService>();
            SiteServicesAndPrices = new List<SiteServicesAndPrice>();
            UserProfiles = new List<UserProfile>();
        }

        [Key]
        public int SiteID { get; set; }
        public string Sitestate { get; set; }
        public int Machid { get; set; }
        public short Labpsc { get; set; }
        public string Labid { get; set; }
        public string AmexId { get; set; }
        public string Payaccount { get; set; }
        public string Ratingid { get; set; }
        public short Active { get; set; }
        public string Comments { get; set; }
        public string Privatecomments { get; set; }
        public string Name { get; set; }
        public int? Mroid { get; set; }
        public int? Datamgmt { get; set; }
        public int? Internalsite { get; set; }
        public int? Testsite { get; set; }
        public Guid MsreplTranVersion { get; set; }
        public int? Taxexempsig { get; set; }
        public int? Reportinghold { get; set; }
        public int? Orderhold { get; set; }
        public int Backgroundsallowed { get; set; }
        public bool AllowPsychemedicsHairTestingForClinicsClients { get; set; }
        public bool IncludeInLabAccountSync { get; set; }
        public bool AllowSsnsearch { get; set; }
        public bool Electronicdotallowed { get; set; }
        public bool ClinicOptedInForRandomsProgram { get; set; }
        public bool? Clinicuploadenabled { get; set; }
        public int ServiceQueueTypeId { get; set; }
        public int FrontOfficeCheckInGroupMode { get; set; }
        public bool Advancedsearch123allowed { get; set; }
        public bool? IsLabFriendly { get; set; }
        public string LabCorpSupplyId { get; set; }
        public string LabCorpSupplyPhoneNumber { get; set; }
        public string LabCorpCourierPhoneNumber { get; set; }


        public virtual List<AlereSite> AlereSites { get; set; }
        public virtual List<AtnSite> AtnSites { get; set; }
        public virtual List<ClientCollSite> ClientCollSites { get; set; }
        public virtual List<CollectionSiteCarrier> CollectionSiteCarriers { get; set; }
        //public virtual CollectionSiteExtra CollectionSiteExtra { get; set; }
        public virtual List<CollectionSiteGroups> CollectionSiteGroups { get; set; }
        public virtual List<CollectionSiteMultiple> CollectionSiteMultiples { get; set; }
        public virtual List<ClinicAttributesAssignment> ClinicAttributesAssignments { get; set; }
        public virtual CollectionSiteOption CollectionSiteOption { get; set; }
        public virtual List<CollectionSitePanel> CollectionSitePanels { get; set; }
        public virtual List<CrlSite> CrlSites { get; set; }
        public virtual List<CsAddress> CsAddresses { get; set; }
        //public virtual HoursOfOperation HoursOfOperation { get; set; }
        public virtual List<ReimbursementHistory> ReimbursementHistories { get; set; }
        public virtual List<SiteDynamicService> SiteDynamicServices { get; set; }
        public virtual List<SiteServicesAndPrice> SiteServicesAndPrices { get; set; }
        public virtual List<UserProfile> UserProfiles { get; set; }
    }
}

CollectionSiteOption class:

namespace DatabaseRefreshRecovery.Models
{
    public class CollectionSiteOption
    {
        [Key, ForeignKey("CollectionSite")]
        public int Siteid { get; set; }
        public string Attainbilltonum { get; set; }
        public int? Posonlyreviewcontract { get; set; }
        public int? Backgroundscontract { get; set; }
        public int? _24hours { get; set; }
        public int? Averifycontract { get; set; }
        public string Connectiontype { get; set; }
        public string Ispnumber { get; set; }
        public string Userid { get; set; }
        public string Password { get; set; }
        public Guid MsreplTranVersion { get; set; }
        public DateTime? CliaExpirationDate { get; set; }



        [XmlIgnore]
        public virtual CollectionSite CollectionSite { get; set; }
    }
}

CollectionSite 的 DBContext:

public DbSet<CollectionSite> CollectionSites { get; set; }

流利API...

//
            modelBuilder.Entity<CollectionSite>().ToTable("COLLECTIONSITE");
            modelBuilder.Entity<CollectionSite>().Property(p => p.MsreplTranVersion).HasColumnName("msrepl_tran_version");
            modelBuilder.Entity<CollectionSite>().Property(p => p.SiteID).HasColumnName("SITEID");
            modelBuilder.Entity<CollectionSite>().Property(p => p.AmexId).HasColumnName("AMEX_ID");
            modelBuilder.Entity<CollectionSite>().Property(p => p.MsreplTranVersion).HasColumnName("msrepl_tran_version");

            modelBuilder.Entity<CollectionSite>().HasMany<ClinicAttributesAssignment>(x => x.ClinicAttributesAssignments).WithRequired(x => x.CollectionSite).HasForeignKey(x => x.SiteId);
            modelBuilder.Entity<CollectionSite>().HasMany<AlereSite>(x => x.AlereSites).WithRequired(x => x.CollectionSite).HasForeignKey(x => x.SiteId);
            modelBuilder.Entity<CollectionSite>().HasMany<AtnSite>(x => x.AtnSites).WithRequired(x => x.CollectionSite).HasForeignKey(x => x.Siteid);
            modelBuilder.Entity<CollectionSite>().HasMany<ClientCollSite>(x => x.ClientCollSites).WithRequired(x => x.CollectionSite).HasForeignKey(x => x.Siteid);
            modelBuilder.Entity<CollectionSite>().HasMany<CollectionSiteCarrier>(x => x.CollectionSiteCarriers).WithRequired(x => x.CollectionSite).HasForeignKey(x => x.SiteID);            
            //modelBuilder.Entity<CollectionSite>().HasOptional<CollectionSiteExtra>(x => x.CollectionSiteExtra).WithRequired(x => x.CollectionSite);
            modelBuilder.Entity<CollectionSite>().HasMany<CollectionSiteMultiple>(x => x.CollectionSiteMultiples).WithRequired(x => x.CollectionSite).HasForeignKey(x => x.Siteid);
            modelBuilder.Entity<CollectionSite>().HasOptional<CollectionSiteOption>(x => x.CollectionSiteOption).WithRequired(x => x.CollectionSite);
            modelBuilder.Entity<CollectionSite>().HasMany<CollectionSitePanel>(x => x.CollectionSitePanels).WithRequired(x => x.CollectionSite).HasForeignKey(x => x.SiteId);
            modelBuilder.Entity<CollectionSite>().HasMany<CrlSite>(x => x.CrlSites).WithRequired(x => x.CollectionSite).HasForeignKey(x => x.Siteid);
            modelBuilder.Entity<CollectionSite>().HasMany<CsAddress>(x => x.CsAddresses).WithRequired(x => x.CollectionSite).HasForeignKey(x => x.Siteid);
            modelBuilder.Entity<CollectionSite>().HasMany<ReimbursementHistory>(x => x.ReimbursementHistories).WithRequired(x => x.CollectionSite).HasForeignKey(x => x.SiteId);
            modelBuilder.Entity<CollectionSite>().HasMany<SiteDynamicService>(x => x.SiteDynamicServices).WithRequired(x => x.CollectionSite).HasForeignKey(x => x.SiteId);
            modelBuilder.Entity<CollectionSite>().HasMany<SiteServicesAndPrice>(x => x.SiteServicesAndPrices).WithRequired(x => x.CollectionSite).HasForeignKey(x => x.Siteid);
            modelBuilder.Entity<CollectionSite>().HasMany<UserProfile>(x => x.UserProfiles).WithRequired(x => x.CollectionSite).HasForeignKey(x => x.Siteid);
            //modelBuilder.Entity<CollectionSite>().HasOptional<HoursOfOperation>(x => x.HoursOfOperation).WithRequired(x => x.CollectionSite);
            modelBuilder.Entity<CollectionSite>().HasMany<CollectionSiteGroups>(x => x.CollectionSiteGroups).WithRequired(x => x.CollectionSite).HasForeignKey(x => x.Siteid);

CollectionSiteOption 的 DBContext:

public DbSet<CollectionSiteOption> CollectionSiteOptions { get; set; }

流利API...

//
            modelBuilder.Entity<CollectionSiteOption>().HasKey(e => e.Siteid);
            modelBuilder.Entity<CollectionSiteOption>().ToTable("COLLECTIONSITEOPTIONS", "dbo");
            modelBuilder.Entity<CollectionSiteOption>().Property(e => e.Siteid).HasColumnName("SITEID");

            modelBuilder.Entity<CollectionSiteOption>().Property(e => e.Attainbilltonum)
                .HasColumnName("ATTAINBILLTONUM")
                .HasMaxLength(15)
                .IsUnicode(false);

            modelBuilder.Entity<CollectionSiteOption>().Property(e => e.Averifycontract).HasColumnName("AVERIFYCONTRACT");
            modelBuilder.Entity<CollectionSiteOption>().Property(e => e.Backgroundscontract).HasColumnName("BACKGROUNDSCONTRACT");
            modelBuilder.Entity<CollectionSiteOption>().Property(e => e.CliaExpirationDate).HasColumnType("datetime");

            modelBuilder.Entity<CollectionSiteOption>().Property(e => e.Connectiontype)
                .HasColumnName("CONNECTIONTYPE")
                .HasMaxLength(30)
                .IsUnicode(false);

            modelBuilder.Entity<CollectionSiteOption>().Property(e => e.Ispnumber)
                .HasColumnName("ISPNUMBER")
                .HasMaxLength(10)
                .IsUnicode(false);

            modelBuilder.Entity<CollectionSiteOption>().Property(e => e.MsreplTranVersion).HasColumnName("msrepl_tran_version");

            modelBuilder.Entity<CollectionSiteOption>().Property(e => e.Password)
                .HasColumnName("PASSWORD")
                .HasMaxLength(10)
                .IsUnicode(false);

            modelBuilder.Entity<CollectionSiteOption>().Property(e => e.Posonlyreviewcontract).HasColumnName("POSONLYREVIEWCONTRACT");

            modelBuilder.Entity<CollectionSiteOption>().Property(e => e.Userid)
                .HasColumnName("USERID")
                .HasMaxLength(30)
                .IsUnicode(false);

            modelBuilder.Entity<CollectionSiteOption>().Property(e => e._24hours).HasColumnName("24HOURS");

违规代码方法: 我在有问题的代码行前面加上 *---><---* 前缀。

private CollectionSite GetCollectionSiteInformation(int siteID)
        {
            CollectionSite collectionSite = new CollectionSite();

            SendMessageToUser($"Retrieving the collection site for '{siteID}'.");
            collectionSite = Context.CollectionSites.Where(o => o.SiteID == siteID).SingleOrDefault();
            SendMessageToUser($"Retrieving the clinic attribute assignments & value assignments for '{siteID}'.");
            collectionSite.ClinicAttributesAssignments = Context.ClinicAttributesAssignment.Where(x => x.SiteId == siteID).Include(x => x.ClinicAttributesValueAssignments).ToList();
            SendMessageToUser($"Retrieving the Alere sites for '{siteID}'.");
            collectionSite.AlereSites = Context.AlereSites.Where(x => x.SiteId == siteID).ToList();
            SendMessageToUser($"Retrieving the Atn sites for '{siteID}'.");
            collectionSite.AtnSites = Context.AtnSites.Where(x => x.Siteid == siteID).ToList();
            SendMessageToUser($"Retrieving the client collection sites for '{siteID}'.");
            collectionSite.ClientCollSites = Context.ClientCollSites.Where(x => x.Siteid == siteID).ToList();
            SendMessageToUser($"Retrieving the collection site carrier for '{siteID}'.");
            collectionSite.CollectionSiteCarriers = Context.CollectionSiteCarrier.Where(x => x.SiteID == siteID).ToList();
            //SendMessageToUser($"Retrieving the collection site extras for '{siteID}'.");
            //collectionSite.CollectionSiteExtra = Context.CollectionSiteExtras.Where(x => x.Siteid == siteID).SingleOrDefault();
            SendMessageToUser($"Retrieving the collection site multiples for '{siteID}'.");
            collectionSite.CollectionSiteMultiples = Context.CollectionSiteMultiples.Where(x => x.Siteid == siteID).ToList();
            SendMessageToUser($"Retrieving the collection site groups for '{siteID}'.");
            collectionSite.CollectionSiteGroups = Context.CollectionSiteGroups.Where(x => x.Siteid == siteID).ToList();
            SendMessageToUser($"Retrieving the collection site options for '{siteID}'.");
            *--->collectionSite.CollectionSiteOption = Context.CollectionSiteOptions.Where(x => x.Siteid == siteID).SingleOrDefault();<---*
            SendMessageToUser($"Retrieving the collection site panels for '{siteID}'.");
            collectionSite.CollectionSitePanels = Context.CollectionSitePanels.Where(x => x.SiteId == siteID).ToList();
            SendMessageToUser($"Retrieving the CRL sites for '{siteID}'.");
            collectionSite.CrlSites = Context.CrlSites.Where(x => x.Siteid == siteID).ToList();
            SendMessageToUser($"Retrieving the collection site addresses for '{siteID}'.");
            collectionSite.CsAddresses = Context.CsAddresses.Where(x => x.Siteid == siteID).Include(x => x.Address).ToList();
            SendMessageToUser($"Retrieving the reimbursement histories for '{siteID}'.");
            collectionSite.ReimbursementHistories = Context.ReimbursementHistory.Where(x => x.SiteId == siteID).ToList();
            SendMessageToUser($"Retrieving the site dynamic services for '{siteID}'.");
            collectionSite.SiteDynamicServices = Context.SiteDynamicServices.Where(x => x.SiteId == siteID).ToList();
            SendMessageToUser($"Retrieving the site services & prices for '{siteID}'.");
            collectionSite.SiteServicesAndPrices = Context.SiteServicesAndPrices.Where(x => x.Siteid == siteID).ToList();
            SendMessageToUser($"Retrieving the user profiles for '{siteID}'.");
            collectionSite.UserProfiles = Context.UserProfiles.Where(x => x.Siteid == siteID).Include(x => x.Mach).ToList();
            //SendMessageToUser($"Retrieving the hours of operation for '{siteID}'.");
            //collectionSite.HoursOfOperation = Context.HoursOfOperation.Where(x => x.Siteid == siteID).SingleOrDefault();

            return collectionSite;
        }

堆栈跟踪:

   at System.Data.Entity.Core.Objects.EntityEntry.WillNotRefSteal(EntityReference refToPrincipal, IEntityWrapper wrappedPrincipal)
   at System.Data.Entity.Core.Objects.EntityEntry.FixupEntityReferenceToPrincipal(EntityReference relatedEnd, EntityKey foreignKey, Boolean setIsLoaded, Boolean replaceExistingRef)
   at System.Data.Entity.Core.Objects.EntityEntry.FixupReferencesByForeignKeys(Boolean replaceAddedRefs, EntitySetBase restrictTo)
   at System.Data.Entity.Core.Objects.ObjectStateManager.FixupReferencesByForeignKeys(EntityEntry newEntry, Boolean replaceAddedRefs)
   at System.Data.Entity.Core.Objects.ObjectStateManager.AddEntry(IEntityWrapper wrappedObject, EntityKey passedKey, EntitySet entitySet, String argumentName, Boolean isAdded)
   at System.Data.Entity.Core.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func`2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet)
   at System.Data.Entity.Core.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper)
   at System.Data.Entity.Core.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext()
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at DatabaseRefreshRecovery.Processess.Clinics.GetCollectionSiteInformation(Int32 siteID) in C:\development\escreen\DEV-TOOLS\DatabaseRefreshRecoveryTool\DatabaseRefreshRecovery\Processes\Clinics.cs:line 137
   at DatabaseRefreshRecovery.Processess.Clinics.RetrieveUserData() in C:\development\escreen\DEV-TOOLS\DatabaseRefreshRecoveryTool\DatabaseRefreshRecovery\Processes\Clinics.cs:line 48
   at DatabaseRefreshRecovery.DatabaseRefreshRecoveryForm.ProcessCollectionSites() in C:\development\escreen\DEV-TOOLS\DatabaseRefreshRecoveryTool\DatabaseRefreshRecovery\DatabaseRefreshRecoveryForm.cs:line 159
   at DatabaseRefreshRecovery.DatabaseRefreshRecoveryForm.ProcessBackup() in C:\development\escreen\DEV-TOOLS\DatabaseRefreshRecoveryTool\DatabaseRefreshRecovery\DatabaseRefreshRecoveryForm.cs:line 88

通过添加 .Map() 定义外键解决了我的问题。认为外键需要在一对一关系上定义,但不知道如何定义,我通过 API 找到的一对一关系示例没有定义它。

modelBuilder.Entity<CollectionSite>().HasOptional<CollectionSiteOption>(x => x.CollectionSiteOption).WithRequired(x => x.CollectionSite).Map(x => x.MapKey("Siteid"));