MetadataWorkspaceExtensions.GetDbProviderManifest in Entity Framework 6.0 - entity-framework

In EF 5, there was a T4 utility template named GenerateEDM.Utility.ttinclude that started with the following code:
internal DbProviderManifest GetDbProviderManifest(string providerInvariantName, string providerManifestToken)
{
DbProviderManifest providerManifest = null;
try
{
providerManifest = MetadataWorkspaceExtensions.GetDbProviderManifest(providerInvariantName, providerManifestToken);
}
Now I'm rewriting some of our EF5 code generation templates for EF6, and I cannot find the method MetadataWorkspaceExtensions.GetDbProviderManifest.
Where was this method moved to in Entity Framework 6.0?

Related

How to get entity validation errors in Entity Framework Core 3.1.31

I'm trying to migrate an older EF6 project to a NetStandard 2.0 EF Core 3.1.31 project. One of the final issues I'm running into is catching and reporting entity validation errors. This is what we had previously.
catch (DbEntityValidationException dbexc)
{
var sb = new StringBuilder();
foreach (var eve in dbexc.EntityValidationErrors)
{
sb.AppendLine($"Entity of type {eve.Entry.Entity.GetType().Name} in state {eve.Entry.State} has the following validation errors:<br />");
foreach (var ve in eve.ValidationErrors)
{
sb.AppendLine($" - Property: {ve.PropertyName}, Error: {ve.ErrorMessage}<br />");
}
}
retval.ErrorMessages.Add(sb.ToString());
}
I can't find clear direction on how to do something similiar in EF Core.

Entity Framework Core 1.0 CurrentValues.SetValues() does not exist

I'm attempting to update an entity and its related child entities using Entity Framework Core 1.0 RC 1, where the entities are detached from DbContext. I've done this previously using a solution similar to the one described in this answer.
However, it seems that we are no longer able to do the following using Entity Framework 7:
DbContext.Entry(existingPhoneNumber).CurrentValues.SetValues();
Visual Studio complains that:
EntityEntry does not contain a definition for 'CurrentValues'
etc...
I presume this means that this has not (yet?) been implemented for EF Core 1.0? Apart from manually updating the properties, is there any other solution?
As you have noticed, this API is not implemented yet in EF Core. See this work item: https://github.com/aspnet/EntityFramework/issues/1200
I know this is an old question but I ran into this issue today, and it appears it still isn't implemented in EF Core. So I wrote an extension method to use in the meantime that will update any object's properties with the matching values of any other object.
public static class EFUpdateProperties
{
public static TOrig UpdateProperties<TOrig, TDTO>(this TOrig original, TDTO dto)
{
var origProps = typeof(TOrig).GetProperties();
var dtoProps = typeof(TDTO).GetProperties();
foreach(PropertyInfo dtoProp in dtoProps)
{
origProps
.Where(origProp => origProp.Name == dtoProp.Name)
.Single()
.SetMethod.Invoke(original, new Object[]
{
dtoProp.GetMethod.Invoke(dto, null) });
}
);
return original;
}
}
Usage:
public async Task UpdateEntity(EditViewModel editDto)
{
// Get entry from context
var entry = await _context.Items.Where(p => p.ID == editDto.Id).FirstOrDefaultAsync();
// Update properties
entry.UpdateProperties(editDto);
// Save Changes
await _context.SaveChangesAsync();
}

Using MiniProfiler in N-Tier Framework

I have a MVC 4 Web Application that uses a BLL and DAL. The DAL uses EF6 and the model first approach. I would like to setup MiniProfiler to profile the web and database calls. I've added MiniProfiler and MiniProfiler.MVC4 through Nuget and it is up and running on the website.
My question is, how can I setup the BLL and DAL to return EF calls with query information?
Here is how the projects are setup:
Web Layer - Reference to MiniProfiler, MiniProfiler.MVC, and BLL Project. The Controllers make the call to the BLL methods.
BLL - Reference to MiniProfiler and the DAL Project. BLL methods make a call to the DAL methods.
DAL - Reference to MiniProfiler and MiniProfiler,EF5. DAL methods make a call to the database using Linq.
Just based on that setup, I can get MiniProfiler data from the BLL but I'm not getting any EF SQL data.
Ok, I got it figured out. Here is how to setup your N-Tier projects to support MiniProfiler:
Web Layer - Add a reference to MiniProfiler, MiniProfiler.MVC, MiniProfiler.EntityFramework and BLL Project. In the Global.asax, make sure to turn on EF Profiling:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
// Entity Framework Profiling
MiniProfilerEF.Initialize();
}
Here is an example of a controller calling the BLL with profiling:
[HttpGet]
public ActionResult Index()
{
var profiler = MiniProfiler.Current;
using (profiler.Step("Web Controller"))
{
Employee bll = new Employee();
int value = bll.GetLastEmployeeID();
}
return View();
}
BLL - Add a reference to MiniProfiler and the DAL Project. BLL methods make a call to the DAL methods.
Here is an example of the a BLL method calling the DAL with profiling:
public int GetLastEmployeeID()
{
int result = 0;
var profiler = MiniProfiler.Current;
using (profiler.Step("BLL - GetLastEmployeeID"))
{
EmployeeDAO dao = new EmployeeDAO();
result = dao.GetLastEmployeeID();
}
return result;
}
DAL - Add a reference to MiniProfiler and MiniProfiler,EF5. DAL methods make a call to the database using Linq. For example:
public int GetLastEmployeeID()
{
int id = 0;
using (var context = new CompanyEntities())
{
var lastEmployee = (from e in context.Employees
where e.IsDeleted == false
orderby e.EmployeeID descending
select e).First();
id = lastEmployee.EmployeeID;
}
return id;
}
Using this setup, I am able to get the EF profiling with SQL to display in MiniProfiler on the Web Site.

Entity Framework 5 Generates SQL Referencing NotMapped Property

I just set about updating a project from Entity Framework 4.3.1 and .NET 4 to Entity Framework 5.0 and .NET 4.5. I updated the .NET version first, and ensured that I'm referencing EF 5.0.0.0 rather than the .NET 4 compatible 4.4.0.0.
I have a class structure like
public class MyBase
{
[NotMapped]
public bool MyProperty { get; set; }
}
public class MyDefinition : MyBase
{
// Some other properties
}
When I attempt to load some MyDefinition instances
using (MyContext ctx = new MyContext())
{
ctx.Configuration.AutoDetectChangesEnabled = false;
ctx.Configuration.LazyLoadingEnabled = false;
ctx.Configuration.ProxyCreationEnabled = false;
var defs = from def in ctx.MyDefinitions.AsNoTracking() select def;
foreach (MyDefinition def in defs) // <-- Exception here
{
// Do stuff
}
}
I get a SqlException
Invalid column name 'MyProperty'.
It is as if NotMapped is respected for purposes of determining whether the existing schema is valid, but the SELECT generated by EF 5 expects there to be a MyProperty column.
The base class and derived class are defined in different assemblies. Both assemblies were carefully checked to ensure they reference EF 5.0.0.0 and target .NET 4.5.
Intellisense claims that NotMapped is System.ComponentModel.DataAnnotations.Schema.NotMapped
How can I prevent EF 5 from selecting that non-existent column?
Add this
using System.ComponentModel.DataAnnotations.Schema
D'oh!
I also updated to VS 2012 today. Something unrelated broke with a post-build event, which caused an earlier version of the assembly containing the base class to be available to the derived class. Fixing the post build event resolved the issue.

how to use mvc-mini-profiler for database-first entity framework?

I am trying to use mvc-mini-profiler for db-first EF, but it is not working properly.
(note that I'm using objectcontext, not dbcontext)
Here is the list of stackoverflows I've tried:
Setup of mvc-mini-profiler for EF-db- first
How to get MVC-mini-profiler working on EF 4.1 Database First
versions:
Entity Framework: 4.3.1
MiniProfiler: 2.0.2
MiniProfiler.ef: 2.0.3
This is how I setup miniprofiler:
I've added the following stuff in Global.asax
protected void Application_BeginRequest(
{
MiniProfiler.Start();
}
protected void Application_EndRequest()
{
MiniProfiler.Stop();
}
protected void Application_Start()
{
...
MiniProfilerEF.Initialize_EF42();
}
Then configure an objectcontext,
var entityConnection = new EntityConnection(ConnectionString);
var profiledDbConnection = new EFProfiledDbConnection(entityConnection, MiniProfiler.Current);
var context = profiledDbConnection.CreateObjectContext<MyContext>();
var list = context.MyEntities.ToList();
If I execute this, the following exception occurs when running "context.MyEntities.ToList()"
[System.Data.EntityCommandCompliationException]
the message in the inner exception says:
EntityClient cannot be used to create a command definition from a store command tree.
Have I configured wrong? Any help?
thanks,
I use MiniProfiler and database first Entity Framework and it does work well. You may need to turn off the database initialization strategy inside of your database context as per this related answer: https://stackoverflow.com/a/9762989/325727
public class EmployeeContext : DbContext
{
static EmployeeContext() { Database.SetInitializer<EmployeeContext>(null); }
public IDbSet<Employee> Employees { get; set; }
}
The parameter null turns off database initialization by making sure that there is no initializer available.