Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DbContext not initializing with SQL Server Compact in ASP.Net MVC

I have created a simple project using ASP.Net MVC template in Visual Studion 2013 Express for Web. It does not use any authentication. Then I installed EntityFramework (v6.0.1), EntityFramework.SqlServerCompact packages.

My DbContext class is very simple:

public class EditTestContext : DbContext
{
    public EditTestContext() : base("EditTestContext")
    {
    }

    public EditTestContext(string connectionString) : base(connectionString)
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.SetInitializer(
                       new DropCreateDatabaseIfModelChanges<EditTestContext>());
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

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

The actual context object is created in the Unit of Work class:

public class EditTestUoW:IEditTestUoW,IDisposable
{
    private DbContext dbContext;

    public EditTestUoW()
    {
        CreateDbContext();
    }

    private void CreateDbContext()
    {
        dbContext = new EditTestContext();//NEW DBCONTEXT OBJECT IS CREATED
        dbContext.Configuration.LazyLoadingEnabled = false;
        dbContext.Configuration.ProxyCreationEnabled = false;
        dbContext.Configuration.ValidateOnSaveEnabled = false;
    }

    public IRepository<EditTestModel> EditTestRepo
    {
        get 
        {
            return new EFRepository<EditTestModel>(dbContext);
        }
    }
}

The connection string being used is:

<add name="EditTestContext" connectionString="Data Source=
    |DataDirectory|EditTestDb.sdf;Max Database Size=256;
    Max Buffer Size=1024;File Mode=Shared Read;
    Persist Security Info=False;" providerName="System.Data.SqlServerCe.4.0" />

Now when I try to access any thing using this Context like:

var rep=UoW.EditTestRepo;
var list=rep.GetAll().ToList();

I am getting following exception on rep.GetAll() function:

System.InvalidOperationException: Sequence contains no matching element

On digging deeper, IQueryable from Repository class (DbSet<EditTest>) is throwing following exception:

The context cannot be used while the model is being created. This exception may
be thrown if the context is used inside the OnModelCreating method or if the same
context instance is accessed by multiple threads concurrently. Note that instance
members of DbContext and related classes are not guaranteed to be thread safe.

I thought it might have been caused by ninject, but it is still there even after I removed it.

What I am doing wrong here or something (some assembly reference etc.) is missing?

like image 442
TheVillageIdiot Avatar asked Dec 13 '13 00:12

TheVillageIdiot


1 Answers

Well after some other search on the issue, I got this MSDN forum link. As was suggested by Rowan, I tried to manually initialize the context using following statement in my EFRepository class:

dbContext.Database.Initialize(false);

The application failed way before it was hitting the GetAll() method. But this exposed the stack trace which gave me some direction:

[InvalidOperationException: Sequence contains no matching element]
   System.Linq.Enumerable.Single(IEnumerable`1 source, Func`2 predicate) +2614017
   System.Data.Entity.Utilities.DbProviderManifestExtensions.GetStoreTypeFromName
                        (DbProviderManifest providerManifest, String name) +146
   .....Other Lines.....
   System.Data.Entity.Internal.InternalContext.Initialize() +31
   System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType
                                                            (Type entityType) +38
   System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() +138
   System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext() +38
   System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable
                      .get_Provider() +99
   System.Linq.Queryable.Any(IQueryable`1 source) +50

Then searching for DbProviderManifestExtensions.GetStoreTypeFromName revealed that this is the line where EF was trying to get column type. I had specified UNIQUEIDENTIFIER for my Id column:

Property(x=> x.Id).HasColumnType("UNIQUEIDENTIFIER")

Once I commented this, all was well.

Though there is a request on Codeplex to provide the proper error message in case the column type is not valid for database provider.

like image 174
TheVillageIdiot Avatar answered Oct 29 '22 17:10

TheVillageIdiot