1
votes

Background:

I have a Web API project and a Class Library project in the same solution that share the same Model classes. Both projects share the same database and both use DbContext to read/write data.

The Web API project is set up in the typical UnitOfWork pattern and works just fine.

The class project is a bit different. I specify the connection string in the constructor instead of the Web.config file:

class MyContext : DbContext
{
    public MyContext(string connectionString)
        : base()
    {
        // Do this to force me to use eager loading
        this.Configuration.LazyLoadingEnabled = false;
        // Init connection string
        this.Database.Connection.ConnectionString = connectionString;
        Database.SetInitializer <CFCalcContext> (null);
    }


    ... DbSets ...

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        ... modelBuilder details ...
    }
}

I use the Web API to call a function defined in the class library. When I attempt to query the database using the class library I get an error.

The Problem:

In the class library project I get a EntityCommandCompilationException with the inner exception as:

InnerException: System.Data.MappingException HResult=-2146232032 Message= (82,10) : error 3034: Problem in mapping fragments starting at lines 82, 90:Two entities with different keys are mapped to the same row. Ensure these two mapping fragments do not map two groups of entities with different keys to the same group of rows.

(82,10) : error 3034: Problem in mapping fragments starting at lines 82, 98:Two entities with different keys are mapped to the same row. Ensure these two mapping fragments do not map two groups of entities with different keys to the same group of rows.

(82,10) : error 3034: Problem in mapping fragments starting at lines 82, 106:Two rows with different primary keys are mapped to the same entity. Ensure these two mapping fragments do not map two groups of entities with identical keys to two overlapping groups of rows.

(82,10) : error 3034: Problem in mapping fragments starting at lines 82, 112:Two entities with different keys are mapped to the same row. Ensure these two mapping fragments do not map two groups of entities with different keys to two overlapping groups of rows.

(82,10) : error 3034: Problem in mapping fragments starting at lines 82, 118:Two entities with different keys are mapped to the same row. Ensure these two mapping fragments do not map two groups of entities with different keys to two overlapping groups of rows.

(90,10) : error 3034: Problem in mapping fragments starting at lines 90, 98:Two entities with different keys are mapped to the same row. Ensure these two mapping fragments do not map two groups of entities with different keys to the same group of rows.

Also, when I right click the derived DbContext class (in the class library) and use Entity Framework Power Tools to "View Entity Data Model" I get the error: "A constructible type deriving from DbContext could not be found in the selected file." This works just fine in the Web API project.

Why would two DbContexts that connect to the same database and are configured basically the same perform differently? I must be missing a configuration step, but I don't know which.

Thanks for the help!

1
Could this be a problem with having two DbContext's running at once (one in the Web API and one in the dll)? entityframework.codeplex.com/… - brudert

1 Answers

0
votes

A lot going on here. Firstly, if you're manually setting the connection string you should be setting it in the call to the base constructor:

public MyContext(string connectionString)
    : base(connectionString)

Secondly though, you should really be putting that in Web.Config - if the name is the issue, you can give it a different name like:

public MyContext()
    : base("Whatever name I used in Web.Config")

Third this is probably just wrong:

Database.SetInitializer <CFCalcContext> (null);

The documentation for Database.SetInitializer states:

Gets or sets the database initialization strategy. The database initialization strategy is called when DbContext instance is initialized from a DbCompiledModel.

In other words setting it to null is likely to make your DbContext explode as soon as it tries to do anything - I suspect that's what's happening to you here.