I implemented the T4 Repository/ Unit of Work templates by Gil Fink for use in a project I am working on, my first full scale project using MVC. I am, however, getting an error I wasn't getting before, and I can't track it down. I don't know if it's something with the templates, or just a setting somewhere I have set wrong, but I am at a lose right now. I was hoping someone would be able to shed some light on the situation.
Here's my framework setup:
MVC 3 Beta
SQL Server 2008 R2
Ninject v2.1.0.76
EF4 POCO
3 projects in the solution: Data, Entities and the MVC app.
I am doing a DB first design, and using EF to create the POCO classes, via Microsoft's ADO.NET POCO Entity Generator. I then use the T4 tool to create the repository and unit of work patterns. With that setup, and all the classes and repositories generated, I implement it into the MVC app using Ninject for DI. I am using the MVC 2 method using a Controller Factory at this point, with plans to later change it to the IDependencyResolver method.
When I use a hard-coded Mock repository, the application works as it should, however when I change it to use the IRepository binding, I get the following error:
"The supplied connection is not valid because it contains insufficient mapping or metadata information.
Parameter name: connection"
This indicates to me that the connection string for EF to connection to the DB is incorrect, however it is the default string generated by the ADO.NET Entity Data Model template. Perhaps it is also something with the .edmx settings.
Here is my connection string (using the handy Nerd Dinner database layout)
<add name="NerdDinnerEntities"
connectionString="metadata=
res://*/Model1.csdl|
res://*/Model1.ssdl|
res://*/Model1.msl;
provider=System.Data.SqlClient;
provider connection string="Data Source=Wayne;Initial Catalog=NerdDinner;Integrated Security=True;Pooling=False;MultipleActiveResultSets=True""
providerName="System.Data.EntityClient" />
Anyone with any thoughts/ hints, etc, I would be extremely appreciative.
Edit: here's the link for the T4 template I'm using:
Repository and Unit of Work T4 Template for Entity Framework
Edit2:
The error is something to do with home I'm using DI with Unit Of Work. when I remove DI, and manually have the dependencies in the controllers, it works. When I try to implement DI, it breaks.
res://*/Model1.csdl|
That * is a wildcard that says to EF "scan all the assemblies for the resource". Chances are this scan isn't finding the assembly for whatever reason.
Change * to your assembly name:
res://My.Assembly.Name/Model1.csdl|
If you are using NuGet to install your Ninject dependency, it likes to set up your DI bindings in NinjectWebCommon.cs. If loading your DI bindings requires an Entity Framework context to be instantiated, this happens too early in the application lifecycle and the application can't interpret the connection string properly.
If you think this is may be what's happening to you, see my answer here for more information.
Related
I updated an ASP.NET MVC5 application from EF4 to EF6 and so changed all references from System.Data.EntityClient to System.Data.Entity.Core.EntityClient.
However, the application won't work -- it throws a 500 server error, "connection string doesn't work with this version of EF" -- unless I change the providerName attribute of the connection string back to System.Data.EntityClient!
I'm not even quite sure how it gets a reference to System.Data.EntityClient in the first place -- the app is using all EF6 DLLs.
Perhaps relevant:
I wanted to avoid updating my ObjectContext to a DbContext so I used the available EF 6.x EntityObject Generator to create my entity model. But the generated classes are headed with using System.Data.Entity.Core.EntityClient; as they should be.
The data provider is MySql (provider=MySql.Data.MySqlClient;), using MySQL Connector 6.9.6.
I have simple scenario:
Web Project(C#) with added dll reference to below DataSource project.
Separate DataSource project (Class Library) where I added edmx file and generated POCOs with DbContext Generator.
Really, nothing special. I think every youtube instructional video I saw on Entity Framework is doing something simple.
What I discovered is that EntityDataSource simply doesn't work. I get range of error messages and I really can't see the pattern when they are showing up:
Here are some:
- Unable to load the specified metadata source
- Schema invalid and types cannot be loaded because the assembly contains EdmSchemaAttribute... loading by both name and attribute is not allowed.
Few time, don't know how, I managed to pass by this error, in that case I would get CLR error when I try to execute simple page with datasource and gridview (nothing was coded)
End to add to the problem...
I am referencing another DataSource project the same way. I am perfectly able to set this EntityDataSource without errors above. But when I click Refresh Schema, I get error "Could not find the CLR type for MyEntity.
What is wrong here.
Thanks
I was getting the EdmSchemaAttribute error message, using EF 5.0 and WCF Data Services 5.2.0. This was a data service using a DbContext-derived class, but the DbContext-derived class was in the same assembly as some EDMX files and ObjectContext-based code generated from the EDMX files.
The fix for me was to separate code-first EF code from model-first EF code (which uses ObjectContext and generates code with the [EdmSchema] attribute). By moving the code-first code into a separate assembly, the error message went away and things are working.
I hope that helps.
I have set up my MVC app with seperate Class Libraries for my Domain (POCOs) and Repositories. Now my DbConxet is currently in the domain layer and i wanted to add the following:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
but it couldnt find DbModelBuilder. Now I checked my references and noticed it was referencing EFCodeFirst0.8/lib/EntityFramework.dll When I changed this to EntityFramework4.2.0.0/lib/EntityFramework.dll DbModelBuilder was available but I get errors because the other projects in my solution (MVC and Repo) are referencing the original dll. So I update them but then the MVC layer has a problem in App_Start/SQLCEEntityFramework.cs
What have I done wrong?! Should I have the OnModelCreating in another part of my app and reset all the references to the original EFCodeFirst0.8/lib/EntityFramework.dll? Or fix up the errors in App_Start/SQLCEEntityFramework.cs?
Thanks all,
James
You are doing it wrong :)
There is really no point in POCO, repository pattern, and all that stuff intended for persistance ignorance, when you have entity framework referenced everywhere and your domain is tied with it.
Your domain should be pure class library (with things like componentmodel, dataannotations of course) without referencing EF.
Then you should have "contract" (that is interface, in another class library) between your MVC app and "all the possible repositories" - also EF agnostic.
And finally you have "one particular implementation" of that contract - your EF repository. That should be the only project referencing EF library.
The point is, that if tommorow your boss comes and says "ok, we switching to nhibernate", you sould replay "no problem, i just write another repository implementing this interface with it and change 1 line in IoC container configuration". And as a bonus, you can update your EF reference in 1 place only :)
Hi i am working on asp.net mvc app now.
I want to put all db logic to my mydbprovider.dll
The problem is in design, how can i change only db provider name in my web.config without recompile my own dll ?
I will use such .net providers as (oracle,mssql,postrgree)
Thanks and sorry for my bad english
as soon as you change the web.config then the site's appDomain will restart. This is unavoidable and only happens in the following scenarios:
Change of web.config
change to bin folder
Trigger of
numRecompilesBeforeAppRestart
what you need to do to be able to swap dal layers easily is to program to interfaces. There will be an interface that implements with the correct methods that you want to use and then any associated dal layer (mysql, sqlserver, oracle) will implement those methods
hopefully that will mean you are not bound to a specific implementation of a dal
paul
I'm trying to find some information on preferred solution setup when using MVC 2 and Entity Framework, and it would seem most intuitive to me to set this web app up in 3 layers:
MyProject.Web (MVC project for presentation)
MyProject.Data (Data gateway layer using Entity Framework to speak to the DB)
MyProject.Tests (Test project as created when setting up a new MVC project)
This seems to be contrary to the examples I'm finding, and the documentation (eg, the NerdDinner example) which see the MVC project as mediating directly with the database. The NerdDinner example puts the data access in a repository class mixed in with the MVC models.
I've tried going with the way which seems best to me, and have created my "ADO.NET Entity Data Model" item in my separate Data project, but this gives me an error when I try to use MVC to list the items in it:
"Unable to load the specified metadata resource."
unless I have a copy of the Entity Data model in my MVC project as well.
Before I go too far down the road of looking into this error, I want to find out if I'm just fighting against the framework for purism when I could just be disciplined with only using data access in my repository.
so:
- Is it even possible or recommended to put my Entity Framework def in this other project?
- Will I be sacrificing certain other MVC features by separating it out in this way? (eg, validation?)
- If I'm heading in the right direction and others agree, are there any other examples or docs out there someone could point me at?
Yes, I think it's a good idea to put your entities in a separate assembly.
One way to fix the "Unable to load the specified metadata resource" error is to specify the assembly in the connection string explicitly:
<connectionStrings>
<add name="MyEntities" connectionString="metadata=res://*/AssemblyName.bin.Namespace.MyEntities.csdl|res://*/AssemblyName.bin.Namespace.MyEntities.ssdl|res://*/AssemblyName.bin.Namespace.MyEntities.msl;provider=System.Data.SqlClient;provider connection string="Data Source=SERVER_NAME;Initial Catalog=DBName;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient"/>
</connectionStrings>
Note, especially, the AssemblyName.bin.Namespace.MyEntities. This is the assembly-qualified resource name (assuming the assembly is called "AssemblyName.dll". You may need to use Reflector to figure it out the first time you do this.
This answer might also be helpful.
It is certainly possible to put your Entity Framework definition in another project. Personally, I keep it in another project if the data layer will need to be shared by multiple interfaces (MVC, WCF, WPF).
Take a look at these two MSDN articles on building and using an EntityConnection.
Build an EntityConnection
Use EntityConnection with an Object Context