Correct way/sequence to create DbContext - c#

What is the correct way to generate a DbContext for my database. (I'm using database first.)
It looks like the EF 6.x DbContext Generator option generates empty files if I don't first create an ADO.NET Entity Data Model (EDMX file).
However, if I create the EDMX file first and then create the DbContext, I seem to get conflicting symbols with errors such as:
The call is ambiguous between the following methods or properties: 'BillsEntities.BillsEntities()' and 'BillsEntities.BillsEntities()'
And
d:\users\jonathan\documents\visual studio 2015\Projects\BillTracking\BillsDomain\BillsModel.Context.cs(23,33,23,48): error CS0111: Type 'Entities' already defines a member called 'OnModelCreating' with the same parameter types
And
d:\users\jonathan\documents\visual studio 2015\Projects\BillTracking\BillsDomain\BillsModel.Context.cs(28,36,28,41): error CS0102: The type 'Entities' already contains a definition for 'Bills'
And
d:\users\jonathan\documents\visual studio 2015\Projects\BillTracking\BillsDomain\BillsModel.Context.cs(29,39,29,47): error CS0102: The type 'Entities' already contains a definition for 'Payments'
And
d:\users\jonathan\documents\visual studio 2015\Projects\BillTracking\BillsDomain\BillsModel.Context.cs(30,39,30,48): error CS0102: The type 'Entities' already contains a definition for 'Utilities'
If that's not enough, I notice every time I generate a new EDMX file it seems to want to create a new connection string in my config file and doesn't seem to give me an option to use the existing one.
Can anyone point me to a resource that provides an example of performing these tasks in the correct way and the correct order? When I Google on this, mostly what I get is code-first articles that don't address this at all.

What is the correct way to generate a DbContext for my database. (I'm using database first.)
If you are using database first, you will need to and ADO.NET Entity Data Model.
It looks like the EF 6.x DbContext Generator option generates empty files if I don't first create an ADO.NET Entity Data Model (EDMX file).
You shouldn't be running any of these commands if you are using database first: Enable-Migrations, Add-Migration, Update-Database. Your first step is to create the EDMX file.
However, if I create the EDMX file first and then create the DbContext, I seem to get conflicting symbols with errors such as:
Once you create your EDMX file, your DbContext will also be created within the file. You can access this file by expanding your edmx file followed you by your .Context.tt and open up your .Context.cs class. Notice how the constructor for this class contains a :base("name=yourdbEntities"), which can be found in your web.config file.
If that's not enough, I notice every time I generate a new EDMX file it seems to want to create a new connection string in my config file and doesn't seem to give me an option to use the existing one.
Comment out your connection string and let it create a new one when you create your edmx file. If all is well, you can come back and delete it.
Here are a couple of resources you may find helpful:
http://www.tutorialspoint.com/entity_framework/entity_database_first_approach.htm
https://www.youtube.com/watch?v=o-cV_fSNMqw
I hope you find this answer helpful.

Related

Entity Framework database connection string and class library without startup project?

I am having a bit of trouble with Entity Framework and class libraries. We already have databases, so I chose to use database first approach to get type safety.
The resulting dll file is supposed to be consumed by another application, which allows creation of custom "agents" in the form of a dll file.
For testing I use PowerShell to instantiate the classes and call their methods.
Now, you might already see the problem. There is no such thing as a startup project. All I have are class libraries to be consumed.
At runtime, EF cannot find app.config file, nor use the connection string therein. Which of course produces following error:
Exception calling "GetPersonStaff" with "0" argument(s): "No connection string named 'StaffEntities' could be found in the application config file."
Then I tried to explicitly give the class inheriting DbContext a connection string. But that led to following error:
Exception calling "GetPersonStaff" with "0" argument(s): "The context is being used in Code First mode with code that was generated from an EDMX file for either Database First or Model First development. This
will not work correctly. To fix this problem do not remove the line of code that throws this exception. If you wish to use Database First or Model First, then make sure that the Entity Framework connection st
ring is included in the app.config or web.config of the start-up project. If you are creating your own DbConnection, then make sure that it is an EntityConnection and not some other type of DbConnection, and t
hat you pass it to one of the base DbContext constructors that take a DbConnection. To learn more about Code First, Database First, and Model First see the Entity Framework documentation here: http://go.micros
oft.com/fwlink/?LinkId=394715"
I am kinda stumped now. I tried to google for a solution, but they all either tell me to change startup project, copy app.config/web.config to startup project, or use explicit connection string. None of which are usable in my use case, I believe.
How should I tackle this problem? Thank you in advance.
Well, I figured this out. The correct approach is "Code First from Database", which allows explicit connection string to be used.

Why didn't my Database.tt file generate POCO classes using PetaPoco?

I have a WebApi project that I have just started. I am trying to add a data access layer to it. I am using PetaPoco (I have a Models folder with a Generated sub-folder that has the .tt and .ttinclude files in it). However when I use 'Run Custom Tool' from the context menu to generate my Poco classes I get nothing. The resulting Database.cs file is essentially empty (the generated initial comment is there but nothing else).
I altered the .tt file to use the name of the connection string I specified in the app.config file. I tested that connection using a test.udl file. The connection is good, and the database has tables in it that have data in them.
I would really like to have Poco classes based on these tables. I really don't want to go back to EF.

How to make Entity Framework DB-first generate single .cs file instead of one file per class

I've an existing database with many (~500) tables and stored procedures. Whenever the database gets updated, I need to re-generate the .edmx file for Entity Framework 6 based on the new schema; the process produces about 500 files, one per each table and at least one per each stored procedure that returns results.
For various reasons, I'd rather have a single file with all classes in it.
I know I can comment out this line <EntityModelName>.tt to consolidate all files:
// fileManager.Process()
However I can do this only after Entity Framework generated 500+ files. Having to do this every few days gets quite annoying.
Updating the .edmx file instead of deleting and re-generating it often results in errors due to DB schema issues that won't be resolved anytime soon.
What would be the best way ensure that only one .cs file generated from the outset? I am willing to go as far as forking EntityFramework, modifying VS templates, or doing other unconventional things as necessary.
You can use this tool which you can configure to generate all your POCOs into a single file (by default) or to separate files, also it has more options can you look at and check through the video exists on the link that I've mentioned.
Remember that you can switch between code-first and database first by just setting the context's initializer to null, so something like :
public class MyDbContext : DbContext
{
static MyDbContext()
{
// I don't want to initialize my database from code, I already have a database.
Database.SetInitializer<MyDbContext>(null);
}
//
//
// you dbsets goes here
}
You can find more details about initialize db contexts here.
So in a few words you can use the tool to generate the POCOs for you and still use your database, which is much cleaner than using EDMX files.
Let me know if you need more details or if you still confused.

EF Database first how to update model for database changes?

In a class library Ado.net Entity Data Model is has generated POCO classes. These were generated fine for the first time. But database changes are not being reflected. In edmx diagram right clicking and choosing Update Model from Database show newly created table but it do not add table even after selecting it to add.
I tried running .tt (by right click and Run custom tool) but even it did not regenerated the Poco classes as per latest DB changes.
Help please
Not a fix but a workaround: Is it not an option to simply remove and regenerate the EDMX and the generated classes? That's what I do, it is much easier than working with the update feature, and the result seems to be the same. Your POCO extensions still remain the same and functional.
I use database first and I have my SQL upgrade scripts, the generated EDMX and my Generated models in source control and the changes there are very easy to manage. Here is a rough outline of my DB upgrade process for each version:
Create .sql script for the upgrade, statements like CREATE TABLE etc.
Delete generated files: Model.Context.tt, Model.tt, Model.edmx
Remove Entities string from Web.config (if you use it)
Create the EDMX and Context files the same way you did for the first time
If you use source control (I hope you do!) check what has changed
Test
Commit!
In my case i needed to save ModelName.edmx, then classes were generated.
Ensure that connections string in app.config is correct. I was using a DataDictionary and my connection string had the following path:
data source=|DataDirectory|*.sqlite
Thus, it wasn't updating. Because this DataDirectory variable was being resolved at runtime.

Adding second .edmx file makes first one stop working with metadata error upon entity object creation

After a git merge of a branch that uses the Entity framework, using Entities on a different database have stopped working with the error "The member with identity 'Path.To.Class' does not exist in the metadata collection."
This error is encountered when the following line of code executes:
var databaseTable = database.CreateObject<Table>();
Looking online others solved this by verifying the files were named the same, etc. I have done this but with no luck. Where is this metadata stored and set and what can I do to fix it?
UPDATE: by manually merging in one file at a time, what seems to cause this error to start happening is when adding another .edmx file to the .csprodj file. Also, by deleting the other .edmx file it also started working again. In other words: including a second .edxm file in the same project is breaking the first! How can I solve this!
We were able to fix this by deleting the two .edmx and associated .tt files and then for each we:
Created new ADO .NET Entity Data Model
Kept all names automatically generated from importing from the database untouched
Added code generation from the .edmx file itself and used ADO .NET EntityObject Generator (resulting in a single .tt file for each)
Updated our code (need to access new entity names) and configuration files (change entity name for connection strings)
My guess is somewhere things got incompatible, particuarlly on how we added code generation items. Prior to this "delete everything and try again" solution we used to have multiple .tt files for a single .edmx file--but this is no longer the case.

Categories

Resources