[英]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.