3

I was using EF6's fluent mapping like this:

public SomeClass
{
    public int SomeID { get; set; }
}

public SomeClassMap : EntityTypeConfiguration<SomeClass>
{
    public SomeClassMap()
    {
        ToTable("SomeTable");
        HasKey(c => c.SomeID);
    }
}

And building the configuration from the assembly of the first requested type (model):

public class MyContext : DbContext
{
    private Assembly _assembly;

    public MyContext(string connectionName, Type type)
    {
        //checks
        Database.Connection.ConnectionString = ConfigurationManager.ConnectionStrings[connectionName].ConnectionString;

        _assembly = Assembly.GetAssembly(type);
    }

    public override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //conventions

        //Not the ideal solution, still looking for something better
        modelBuilder.Configurations.AddFromAssembly(_assembly);
    }
}

Now I want to make a generic Data project, independent of the models, so I'd like to map via annotations and simply call the generic methods in my Data project.

I've mapped the class:

[Table("SomeTable")]
public SomeClass
{
    [Key]
    public int SomeID { get; set; }
}

Now how do I pass this to the Data project so it can build the model configuration?

Edit This might be relevant, since my Data project is generic, I don't have the DbSet<Entity> variables in it, instead I'm calling the context.Set<Entity> and using the functions from there.

1 Answer 1

2

You can create a DbContext by the constructor that takes a DbCompiledModel.

You can build the compiled model separately. It's up to you where you want to implement that responsibility, but the model classes should be in scope.

Here's an example:

Some classes:

[Table("Company")]
class Company
{
    [Key]
    public int CompanyID { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Location> Locations { get; set; }
}

[Table("Location")]
class Location
{
    [Key]
    public int LocationID { get; set; }
    public string Name { get; set; }

    [ForeignKey("Company")]
    public int CompanyID { get; set; }
    public virtual Company Company { get; set; }
}

And the creation + usage of a DbContext:

// Create a model + register types to it.
var mb = new DbModelBuilder();
mb.Entity<Company>();
mb.Entity<Location>();

// Or:
//mb.RegisterEntityType(typeof(Company));
//mb.RegisterEntityType(typeof(Location));

// Build and compile the model
var connString = @"server=myServer;database=theDataBase;Integrated Security=SSPI;MultipleActiveResultSets=True";

var dbModel = mb.Build(new SqlConnection(connString));

var compiledModel = dbModel.Compile();

// Create a DbContext using the compiled model.
var db = new DbContext(connString, compiledModel);
Database.SetInitializer<DbContext>(null); // Prevent creation of migration table

// Ready to go!
var companies = db.Set<Company>().Include(c => c.Locations).ToList();

You can make this more efficient by storing and reusing cached DbCompiledModels.

Sign up to request clarification or add additional context in comments.

1 Comment

Worked perfectly, and thank you for the suggestion of caching models!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.