簡體   English   中英

EF6 AssociationType多對多表上的System.InvalidOperationException

[英]System.InvalidOperationException on EF6 AssociationType Many-To-Many Table

我正在使用EF6遷移代碼優先約定來重命名我的所有表,屬性,模式等,以適合我們的內部數據庫約定。 公約正確地重命名了所有的字段和表名稱,按預期進行編譯和腳手架。 但是,當我更新數據庫時,出現以下錯誤:

System.InvalidOperationException: Sequence contains no matching element
   at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
   at System.Data.Entity.Migrations.DbMigrator.FillInForeignKeyOperations(IEnumerable`1 operations, XDocument targetModel)
   at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, VersionedModel targetModel, IEnumerable`1 operations, IEnumerable`1 systemOperations, Boolean downgrading, Boolean auto)
   at System.Data.Entity.Migrations.DbMigrator.ApplyMigration(DbMigration migration, DbMigration lastMigration)
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.ApplyMigration(DbMigration migration, DbMigration lastMigration)
   at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId)
   at System.Data.Entity.Migrations.DbMigrator.UpdateInternal(String targetMigration)
   at System.Data.Entity.Migrations.DbMigrator.<>c__DisplayClassc.<Update>b__b()
   at System.Data.Entity.Migrations.DbMigrator.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.EnsureDatabaseExists(Action mustSucceedToKeepDatabase)
   at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)
   at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)
   at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
   at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
   at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
Sequence contains no matching element

這是導致此問題的表的遷移代碼。 我已經驗證PK正確,外鍵表存在並且類型正確,索引指向正確的字段等。在這里,我全都沒有想法。

CreateTable(
            "cw.map_cw_service_cw_immunization",
            c => new
                {
                    cw_service_id = c.String(nullable: false, maxLength: 36),
                    cw_immunization_id = c.String(nullable: false, maxLength: 36),
                })
            .PrimaryKey(t => new { t.cw_service_id, t.cw_immunization_id })
            .ForeignKey("cw.careware_services", t => t.cw_service_id, cascadeDelete: true)
            .ForeignKey("cw.careware_immunizations", t => t.cw_immunization_id, cascadeDelete: true)
            .Index(t => t.cw_service_id, name: "IX_CarewareService_Id")
            .Index(t => t.cw_immunization_id, name: "IX_CarewareImmunization_Id");

    }

更新:我已將問題縮小為外鍵問題。 如果我注釋掉這兩種外鍵擴展方法,數據庫將按預期更新。 但是,顯然這不是一個有效的解決方法,因為該表現在沒有FK約束。

我根據錯誤堆棧進行了一些挖掘,並在EntityFramework源代碼中找到了以下方法。 該錯誤是由Single()未返回值引起的。 只有一個.Single()操作不會返回默認值,因此顯然是罪魁禍首。 該操作返回與EntitySetName匹配的單個EntityTypeElement(因為它們應該是唯一的)。 長話短說,我意識到我必須在代碼的某個地方意外地更改EntitySet.Name值而不是EntitySet.Table值。 瞧,那是罪魁禍首。 我更改了代碼行,並且效果很好。

TL; DR; -始終檢查以確保您正在設置EntitySet.Table值,並且在更改時未更改EntitySet.Name值。

private void FillInForeignKeyOperations(IEnumerable<MigrationOperation> operations, XDocument targetModel)
{
    DebugCheck.NotNull(operations);
    DebugCheck.NotNull(targetModel);

    foreach (var foreignKeyOperation
        in operations.OfType<AddForeignKeyOperation>()
                     .Where(fk => fk.PrincipalTable != null && !fk.PrincipalColumns.Any()))
    {
        var principalTable = GetStandardizedTableName(foreignKeyOperation.PrincipalTable);
        var entitySetName
            = (from es in targetModel.Descendants(EdmXNames.Ssdl.EntitySetNames)
               where _modelDiffer.GetQualifiedTableName(es.TableAttribute(), es.SchemaAttribute())
                                 .EqualsIgnoreCase(principalTable)
               select es.NameAttribute()).SingleOrDefault();

        if (entitySetName != null) //ERROR SOURCE IS BELOW
        {
            var entityTypeElement
                = targetModel.Descendants(EdmXNames.Ssdl.EntityTypeNames)
                             .Single(et => et.NameAttribute().EqualsIgnoreCase(entitySetName)); 

            entityTypeElement
                .Descendants(EdmXNames.Ssdl.PropertyRefNames).Each(
                    pr => foreignKeyOperation.PrincipalColumns.Add(pr.NameAttribute()));
        }
        else
        {
            // try and find the table in the current list of ops
            var table
                = operations
                    .OfType<CreateTableOperation>()
                    .SingleOrDefault(ct => GetStandardizedTableName(ct.Name).EqualsIgnoreCase(principalTable));

            if ((table != null)
                && (table.PrimaryKey != null))
            {
                table.PrimaryKey.Columns.Each(c => foreignKeyOperation.PrincipalColumns.Add(c));
            }
            else
            {
                throw Error.PartialFkOperation(
                    foreignKeyOperation.DependentTable, foreignKeyOperation.DependentColumns.Join());
            }
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM