实体框架迁移:序列包含多个匹配元素

Posted

技术标签:

【中文标题】实体框架迁移:序列包含多个匹配元素【英文标题】:Entity Framework Migration: Sequence contains more than one matching element 【发布时间】:2017-09-26 07:11:26 【问题描述】:

我们最近对我们的代码库进行了大规模重构(添加一些新实体、更新命名空间、更改导航属性等)

我们在重构之前的代码库有许多实体框架迁移(运行良好)。

但是,在尝试在重构的代码库上运行“update-database”或“add-migration”时,我们收到了Sequence contains more than one matching element 异常。

我们可以解决此问题的唯一方法是完全删除现有的(以前工作的)迁移,并运行“添加迁移”。这显然从头开始生成了一个新的数据库架构,但迁移工作正常。

有没有一种方法可以在不删除现有迁移的情况下继续前进?

在下面运行“更新数据库”找到堆栈跟踪:

System.InvalidOperationException: Sequence contains more than one matching element
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.<>c__DisplayClass24f.<FindAlteredColumns>b__246(<>f__AnonymousType2b`2 <>h__TransparentIdentifier241)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.Diff(ModelMetadata source, ModelMetadata target, Lazy`1 modificationCommandTreeGenerator, MigrationSqlGenerator migrationSqlGenerator, String sourceModelVersion, String targetModelVersion)
   at System.Data.Entity.Migrations.Infrastructure.EdmModelDiffer.Diff(XDocument sourceModel, XDocument targetModel, Lazy`1 modificationCommandTreeGenerator, MigrationSqlGenerator migrationSqlGenerator, String sourceModelVersion, String targetModelVersion)
   at System.Data.Entity.Migrations.DbMigrator.IsModelOutOfDate(XDocument model, 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 more than one matching element

编辑:我现在尝试禁用所有种子数据语句,但问题仍然存在。这里还发现了一个相关问题:http://entityframework.codeplex.com/workitem/569(尽管没有给出解决方案)。

【问题讨论】:

SingleOrDefault 在数据库中必须只有一个元素。如果返回 2,则抛出异常。 是的 - 但我们的迁移实际上都没有使用“SingleOrDefault”。我认为它是由实体框架本身调用的? 您是否使用ColumnAttribute 定义了属性的大小(例如[Column(TypeName="VARCHAR(50)")]?您如何执行Add-Migration 命令(也包括迁移名称)? 不,我们只是将其保留为实体框架的默认值......当我们运行“更新数据库”时也会发生同样的异常......所以我认为它与如何我们实际上运行了命令.. 你的问题是不是类似这样的:entityframework.codeplex.com/workitem/569?您的表是否有独立的关联?通常这与模型生成或DbMigration 有关,在Migrations 目录中显示扩展DbMigration 的模型和迁移代码。 【参考方案1】:

经过多次打击和试验后,我遇到了同样的问题,我发现了这个问题。该问题是由共享相同name 但不同namespace 的两个类引起的;不知何故,EF 忽略了命名空间,并且在更改类名后发生错误,错误消失了。

【讨论】:

从堆栈跟踪来看,这看起来像是有问题的代码; github.com/aspnet/EntityFramework6/blob/master/src/… 我发现 EF Core 团队对错误报告的响应相当迅速,尤其是当我可以追踪问题代码时。 .net 核心代码库将成为 .NET 5,因此值得在那里提出错误。【参考方案2】:

如果 EF 被同名属性混淆,则可能会出现此问题,例如:

public int Username  get; set; 

public int UserName  get; set; 

可能会触发此错误。

【讨论】:

抱歉,我没有仔细检查该代码。错过了大写字母 N。 用户名可能不是int类型,但这不相关

以上是关于实体框架迁移:序列包含多个匹配元素的主要内容,如果未能解决你的问题,请参考以下文章

PetaPoco POCO 生成失败,序列包含多个匹配元素

序列不包含匹配元素 - EntityFramework

Sequence包含多个匹配元素

多个上下文的实体框架迁移脚本故障转移现有的 __MigrationHistory 表

有时实体框架在将“子”添加到新(父)元素后插入多个“父”行

序列包含多个元素 Mvc