In this case, EF4 entities/context are generated by Legacy ObjectContext codegen, DbFirst. The new EF6 entities/context are generated by T4 templates, DbFirst as well.
While there are some hindrances to this transformation, they can be overcome as long as any third party libraries don't use EntityFramework.dll. Let's dive into these details.
The libraries that I've seen are:
- LinqKit containing AsExpandable()/.Invoke(), PredicateBuilder, etc.
- EFExtentions containing Meterializer, .Include(), .SetMergeOption(), CreateStoreCommand(), etc - EOL
- EntityFramework.Extended containing Batch Operations, etc - EOL
As EF4 DbFirst does not depend on EntityFramework.dll, it should be easier to make EF4 code coexist with EF6 code, compared to EF5. This is due to a fact that there is a single depenency on EntityFramework.dll (and, say, EntityFramework.SqlServer.dll). We are going to use this fact. Otherwise, for EF5, one has to resort to assembly aliases, specific assembly deployments, etc.
Note: EF4 code first might have depended on EntityFramework.dll, but I have no experience with this.
There is no way around this - it you've used custom model changes in the EF4 model, namely custom types, navigation/association multiplicity, field renaming, SP mapping, enums, etc, it would not appear in your new model. You will have to do the renaming manually in the new model.
Note again that we are talking about a case whether the previous model is generated by a legacy codegen, while we want a new one to be generated by T4.
Another widely used option for ObjectSet<> is to set its MergeOption to MergeOption.NoTracking. The easiest way of doing so in EF is to call this on DbQuery<> (and not DbSet<>).
We can no longer use a 'Materializer', but there is a better option:
private static readonly Materializer<DummySpReturnType> DummySpReturnTypeMaterializer =
new Materializer<DummySpReturnType>(r => new DummySpReturnType
{
P1 = r.Field<int>("p1"),
P2 = r.Field<string>("p2"),
});
// ...
public void f()
{
using (new TransactionScope(...))
using (var ctx = new YourObjectContextEf4())
{
DummySpReturnTypeMaterializer.Materialize(ctx.CreateStoreCommand(
"ef6_poc",
CommandType.StoredProcedure,
new SqlParameter("input", 1)))
.ToList();
//...
}
}
Becomes:
public void f()
{
using (new TransactionScope(...))
using (var ctx = new YourDbContextEf6())
{
ctx.Database.SqlQuery<DummySpReturnType>("exec ef6_poc @input=1").ToList();
//...
}
}
.AsExpandable(), PredicateBuilder, .Include() remain the same.