2017-05-30 72 views
0

尝试从CSV实体种子国家,但在运行更新数据库时发生此错误。如果我删除表并运行更新数据库,然后错误不会显示,但如果我再次运行更新数据库。序列包含多个元素c#实体种子

CSV文件

Name, 
China, 
India, 
United States, 
Indonesia, 
Brazil, 
Pakistan, 
United Kingdom, 
Bangladesh, 
Russia, 
Japan, 
Mexico, 
Philippines, 
Vietnam, 
Ethiopia, 
Egypt, 
Germany, 
Iran, 
Turkey, 
Democratic Republic of the Congo, 
Thailand, 
France, 
Italy, 
Burma, 
South Africa, 
South Korea, 
Colombia, 
Spain, 
Ukraine, 

我的国家示范

namespace Domain 
{ 
    public class Country : BaseModel 
    { 
     public string Name { get; set; } 
    } 
} 



using System.ComponentModel.DataAnnotations; 

namespace Domain 
{ 
    public class BaseModel 
    { 
     [Key] 
     public int Id { get; set; } 
    } 
} 

种子

var assembly = Assembly.GetExecutingAssembly(); 

const string country = "Service.Migrations.Seed.countries.csv"; 
      using (var stream = assembly.GetManifestResourceStream(country)) 
      { 
       using (var reader = new StreamReader(stream, Encoding.UTF8)) 
       { 
        var csvReader = new CsvReader(reader); 
        csvReader.Configuration.Delimiter = ","; 
        csvReader.Configuration.WillThrowOnMissingField = false; 
        var countries = csvReader.GetRecords<Country>().ToArray(); 
       } 
      } 

错误

No pending explicit migrations. 
Running Seed method. 
System.InvalidOperationException: Sequence contains more than one element 
    at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source) 
    at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__2[TResult](IEnumerable`1 sequence) 
    at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot) 
    at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression) 
    at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression) 
    at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source, Expression`1 predicate) 
    at System.Data.Entity.Migrations.DbSetMigrationsExtensions.AddOrUpdate[TEntity](DbSet`1 set, IEnumerable`1 identifyingProperties, InternalSet`1 internalSet, TEntity[] entities) 
    at System.Data.Entity.Migrations.DbSetMigrationsExtensions.AddOrUpdate[TEntity](IDbSet`1 set, Expression`1 identifierExpression, TEntity[] entities) 
    at Service.Migrations.Configuration.Seed(HotelContext context) in C:\Hotel+\Service\Migrations\Configuration.cs:line 55 
    at System.Data.Entity.Migrations.DbMigrationsConfiguration`1.OnSeed(DbContext context) 
    at System.Data.Entity.Migrations.DbMigrator.SeedDatabase() 
    at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.SeedDatabase() 
    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 element 
+1

通常,当您使用'SingleOrDefault'并且如果该结果包含多于1的结果,那么您会遇到此错误。 –

+0

@PranavPatel,你可以看到csv字段都是唯一的。有什么建议 – rilly009

+0

你能告诉我你的更新代码吗?以及您使用过哪些csvReader? –

回答

1

这就是我解决问题的方法。

var assembly = Assembly.GetExecutingAssembly(); 
const string country = "Service.Migrations.Seed.countries.csv"; 
      using (var stream = assembly.GetManifestResourceStream(country)) 
      { 
       using (var reader = new StreamReader(stream, Encoding.UTF8)) 
       { 
        var csvReader = new CsvReader(reader); 
        csvReader.Configuration.Delimiter = ","; 
        csvReader.Configuration.WillThrowOnMissingField = false; 
        var countries = csvReader.GetRecords<Country>().ToArray(); 
        foreach (var c in countries) 
        { 
         var check = context.Countries.FirstOrDefault(p => p.Name == c.Name); 
         if (check == null) 
         { 
          context.Countries.Add(c); 
          context.SaveChanges(); 
         } 
        } 
       } 
      } 
2

您的ID是自动递增,所以如果你不检查当前国家名称已经在你的数据库,EF将创建一个新的ID的新条目...

你有两个解决方案,以避免这种:

解决方案1:

河套国家内部数据库中,并检查名称已经存在。如果这种情况下不再添加它。

解决方案2:

设置国家名称独特是这样的:

namespace Domain 
{ 
    public class Country : BaseModel 
    { 
     [Index(IsUnique = true)] 
     public string Name { get; set; } 
    } 
} 

这将抛出一个异常时,你会尝试在你的数据库中添加一个名称已退出。例如,您可以使用try-catch来管理错误并记录异常。

+1

感谢下面的建议是我的解决方案。 :) – rilly009

相关问题