初始化实体框架数据库时出错,序列中不包含匹配的元素。

3
我已经盯着这个问题看了5个小时,尝试了很多方法,但是一无所获...当我试图启动使用Entity Framework Code First创建的数据库的MVC网站时,数据库初始化失败,抛出以下异常信息:

Sequence contains no matching elements

堆栈跟踪的第一行执行了Linq .Single查询,因此我认为它正在查找模型中不存在的单个项目。如果正确,如何找出该项目?另外,在达到我的极限并决定在抛出异常后通过所有调试信息后,我注意到我的Autos窗口中有以下内容:

Error message from Autos window

这直接涉及到我的OnModelCreating重写:
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Configurations.Add(new CompanyDBConfiguration());
        modelBuilder.Configurations.Add(new ClientDBConfiguration());
        modelBuilder.Configurations.Add(new QuoteDBConfiguration());
        modelBuilder.Configurations.Add(new RoleDBConfiguration());
        modelBuilder.Configurations.Add(new UserDBConfiguration());
        modelBuilder.Configurations.Add(new InvoiceDBConfiguration());
        modelBuilder.Configurations.Add(new JobDBConfiguration());
        modelBuilder.Configurations.Add(new JobStatusDBConfiguration());            
    }

非常感谢您提供任何有助于解决问题的信息。
非常抱歉,如果这里提供的信息不足,我不知道该提供什么。但以下是堆栈跟踪:(向下滚动以查看编辑)

用户代码未处理System.InvalidOperationException
HResult=-2146233079
Message=序列中没有匹配的元素
Source=System.Core
StackTrace:
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source, Func`2 predicate)
at System.Data.Entity.Utilities.DbProviderManifestExtensions.GetStoreTypeFromName(DbProviderManifest providerManifest, String name)
at System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive.PrimitivePropertyConfiguration.Configure(EdmProperty column, EntityType table, DbProviderManifest providerManifest, Boolean allowOverride, Boolean fillFromExistingConfiguration)
at System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive.PrimitivePropertyConfiguration.<>c__DisplayClass1.b__0(Tuple`2 pm) at System.Data.Entity.Utilities.IEnumerableExtensions.Each[T](IEnumerable`1 ts, Action`1 action)
at System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive.PrimitivePropertyConfiguration.Configure(IEnumerable`1 propertyMappings, DbProviderManifest providerManifest, Boolean allowOverride, Boolean fillFromExistingConfiguration)
at System.Data.Entity.ModelConfiguration.Configuration.Types.StructuralTypeConfiguration.ConfigurePropertyMappings(IList`1 propertyMappings, DbProviderManifest providerManifest, Boolean allowOverride)
at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.ConfigurePropertyMappings(DbDatabaseMapping databaseMapping, EntityType entityType, DbProviderManifest providerManifest, Boolean allowOverride)
at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.Configure(EntityType entityType, DbDatabaseMapping databaseMapping, DbProviderManifest providerManifest)
at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.ConfigureEntityTypes(DbDatabaseMapping databaseMapping, DbProviderManifest providerManifest)
at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.Configure(DbDatabaseMapping databaseMapping, DbProviderManifest providerManifest)
at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo)
at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.LazyInternalContext.MarkDatabaseInitialized()
at System.Data.Entity.Database.Initialize(Boolean force)
at Jobber.Web.MvcApplication.Application_Start() in e:\Development\Jobber\Jobber.Web\Global.asax.cs:line 28
InnerException:

编辑1: 以下是 Global.asax 的代码。
public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        WebApiConfig.Register(GlobalConfiguration.Configuration);
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        BundleConfig.RegisterBundles(BundleTable.Bundles);

        WebDBContext db = new WebDBContext();
        db.Database.Initialize(true);
        db.Seed();
    }
}

这里是WebDBContext()

// BaseDBContext is a generic class that inherits from DbContext, see it's code below
public class WebDBContext : BaseDBContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Configurations.Add(new CompanyDBContext());
        modelBuilder.Configurations.Add(new ClientDBContext());
        modelBuilder.Configurations.Add(new QuoteDBContext());
        modelBuilder.Configurations.Add(new RoleDBContext());
        modelBuilder.Configurations.Add(new UserDBContext());
        modelBuilder.Configurations.Add(new InvoiceDBContext());
        modelBuilder.Configurations.Add(new JobDBContext());
        modelBuilder.Configurations.Add(new JobStatusDBContext());            
    }

    public WebDBContext()
    {
        Database.SetInitializer<WebDBContext>(new DropCreateDatabaseAlways<WebDBContext>());
    }

    public void Seed()
    {
        // seeds initial data into the database
    }

    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }
    public DbSet<Client> Clients { get; set; }
    public DbSet<Company> Companies { get; set; }
    public DbSet<Invoice> Invoices { get; set; }
    public DbSet<Job> Jobs { get; set; }
    public DbSet<JobStatus> JobStatuses { get; set; }
    public DbSet<Quote> Quotes { get; set; }

BaseDBContext:
这个类提供了一个通用的上下文,不针对任何应用程序。这允许为在多个项目之间可能是共同的对象编写CRUD功能。

public class BaseDBContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Configurations.Add(new BaseUserDBContext());
    }

    public BaseDBContext()
        : base()
    {
        Database.SetInitializer<BaseDBContext>(new DropCreateDatabaseIfModelChanges<BaseDBContext>());
    }

    public DbSet<BaseUser> Users { get; set; }
}

编辑 2
Chris 请求 ConnectionString 和我的 UserDBContext(有关此事的更多信息请见下文 - 非常重要的内容)。

  <connectionStrings>
    <add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=aspnet-Jobber.Web-20150105094927;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnet-Jobber.Web-20150105094927.mdf" />
  </connectionStrings>

public class UserDBContext : DBBaseObject<User>
{
    // application-specific columns
    public UserDBContext()
        : base()
    {
        //HasOptional(r => r.Role)
        //    .WithMany(m => m.Users)
        //   .Map(x => x.MapKey("fkRoleID"))
        //    .WillCascadeOnDelete(false);

        ToTable("Users");
    }
}

为了开始解释这个问题,我正在开发一个应用程序框架,它处理所有“全局通用”的结构和方法,也就是说,它处理所有可以逻辑上被认为在应用程序之间共享的东西。
例如,包含用户名和密码的用户对象等。
该框架使用了许多继承、抽象类以及一些泛型。以下是没有这些内容的框架的大致样子:
框架:
Logan.Base
{
    Logan.Base.BaseObject  
    - defines common fields that all tables will always have (PK, auditing, etc)  

    Logan.Base.BaseUser  
    - defines common fields that user tables will have (username, password, etc)
}  
Logan.DBBase  
{
    Logan.DBBase.BaseUserDBContext  
    - defines C#->SQL data type mappings for the BaseUser along with CRUD functions  

    Logan.DBBase.DBBaseObject  
    - defines C#->SQL data type mappings for columns that all tables will always have  

    Logan.DBBase.DBContext  
    - defines a DbContext to be used in the DBBaseObject
}

Logan.Base

namespace Logan.Base
{
    public abstract class BaseObject
    {
        public Int64 PKey { get; set; }
        public Int64 CreatedBy { get; set; }
        public DateTime CreatedOn { get; set; }
        public Int64 ModifiedBy { get; set; }
        public DateTime ModifiedOn { get; set; }

        public BaseObject()
        {
            PKey = 0;
            CreatedBy = 0;
            ModifiedBy = 0;
        }
    }

    public abstract class BaseUser : BaseObject
    {
        public string EmailAddress { get; set; }
        public string Password { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        public BaseUser()
        {
            EmailAddress = String.Empty;
            Password = String.Empty;
            FirstName = String.Empty;
            LastName = String.Empty;
        }        
    }
}

Logan.DBBase

namespace Logan.DBBase
{

    public abstract class DBBaseObject<T> : EntityTypeConfiguration<T>
        where T : BaseObject
    {

        public DBBaseObject()
            : base()
        {
            HasKey(p => p.PKey);
        }
    }

    public class BaseUserDBContext : DBBaseObject<BaseUser>
    {

        // common columns
        public BaseUserDBContext()
            : base()
        {
            Property(p => p.EmailAddress)
                .HasColumnName("sEmailAddress")
                .HasMaxLength(200)
                .IsRequired();

            Property(p => p.Password)
                .HasColumnName("sPassword")
                .HasMaxLength(255)
                .IsRequired();

            Property(p => p.FirstName)
                .HasColumnName("sFirstName")
                .IsRequired();

            Property(p => p.LastName)
                .HasColumnName("sLastName")
                .IsRequired();

            ToTable("Users");
        }

        // User CRUD functions that use the below DbContext go here
    }

    public class BaseDBContext : DbContext
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            modelBuilder.Configurations.Add(new BaseUserDBContext());
        }

        public BaseDBContext()
            : base()
        {
            Database.SetInitializer<BaseDBContext>(new DropCreateDatabaseIfModelChanges<BaseDBContext>());
        }

        public DbSet<BaseUser> Users { get; set; }
    }
}

嗯,了解 e:\Development\Jobber\Jobber.Web\Global.asax.cs:line 28 和它周围的代码可能会有所帮助... - simon at rcl
只需发布包含该行的方法。之后我们会查看。 (编辑问题以添加代码,不要将其作为注释放置-这会变得难以阅读)。 - simon at rcl
@Chris 目前为止,EF 由于此错误无法创建任何数据库。 - Ortund
3
我知道这篇文章已经有些年头了,希望你已经解决了问题。但如果还没有,可以看一下这个答案:https://dev59.com/JWAg5IYBdhLWcg3w9e4y#26156805 - Adil Mammadov
1
@AdilMammadov,没错!谁遇到了这个奇怪的错误,请检查您的属性,特别是如何为nvarchar指定长度。详见链接。 - StalkAlex
显示剩余14条评论
2个回答

3

对我来说,问题出在我的表中有一个SQL_VARIANT类型的列。一旦我将其更改为nvarchar,错误就消失了。


0

我认为你的DBContext有一些问题。我会回到基础,一旦我让DB初始化工作起来,我就会开始添加东西。所以首先,放弃BaseDbContext并将WebDBContext更改为:

public class WebDBContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Configurations.Add(new CompanyDBContext());
        modelBuilder.Configurations.Add(new ClientDBContext());
        modelBuilder.Configurations.Add(new QuoteDBContext());
        modelBuilder.Configurations.Add(new RoleDBContext());
        modelBuilder.Configurations.Add(new UserDBContext());
        modelBuilder.Configurations.Add(new InvoiceDBContext());
        modelBuilder.Configurations.Add(new JobDBContext());
        modelBuilder.Configurations.Add(new JobStatusDBContext());            
    }

    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }
    public DbSet<Client> Clients { get; set; }
    public DbSet<Company> Companies { get; set; }
    public DbSet<Invoice> Invoices { get; set; }
    public DbSet<Job> Jobs { get; set; }
    public DbSet<JobStatus> JobStatuses { get; set; }
    public DbSet<Quote> Quotes { get; set; }
}  

小步慢走。先让它工作起来,然后如果仍然需要,我们可以添加其余的配置。


好的,我已经注释掉除了你展示的内容以外的所有内容,并且我已经使用DbContext代替BaseDBContext,但是什么也没有改变。有趣的是,在此之前,我已经逐步执行过这个步骤,但是这一步并没有以任何方式改变实际执行的代码。 - Ortund
你的UserDbContext在哪里?我没有看到它:modelBuilder.Configurations.Add(new UserDBContext()); - Chris
所有内容已添加在编辑2下。 - Ortund

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接