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.
Related
I have created an ASP.NET Core web application using the MVC pattern (by following this tutorial) and connected it to a local database that is now populated with some data. I have two questions, if someone please help me understand and answer them:
1) My default connection string is set to the following:
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-MyAppName;Trusted_Connection=True;MultipleActiveResultSets=true"
}
Is it possible, only by changing the name and path in this connection string, to re-create the exact same database elsewhere with the data that is currently stored in it (for example, as backup)?
I have found the local database here:
C:\Users\my-name\AppData\Local\Microsoft\Microsoft SQL Server Local DB\Instances\MSSQLLocalDB
But when I try to copy the .mdf file to back up the database, I get an error that says the file is open and cannot be copied. What is it open in? How can I simply back the db file up?
2) After creating a custom controller, I noticed that all the provided properties of my Personmodel are used in the auto-generated code; e.g. in my case:
public async Task<IActionResult> Create([Bind("Birthday,ID,Username,EmailAddress")] PersonModel personModel)
I thought this would mean that if we change the code in the model class, we need to search for and effect the changes accordingly, but then I realized if I want to keep using auto-generated code, I have to do all the same steps as when I am generating it for the first time, and then when it asks if I want to replace the old code with new code, I choose yes.
Is there a better way of doing this, because this would overwrite my custom code every time and destroy the data stored in my local database. Particularly, when I store data in its local database, and then I decide to change a column name or add something, this would override everything...
How do I go about this situation?
Question 1
The .mdf and other files associated with the database will be in use by the SQL Server service. If you want to take a backup, use SQL Server Management Studio - right-click the database in the object explorer, select Tasks and then Backup. If you want to use the backup database then you need to restore it - again in the object explorer, right-click the "Databases" folder and select Restore Database and then browse to wherever you created the backup file.
Question 2 (updated 7th Sep)
When you change your model classes, you can use the add-migration command in the console to generate a new migration class containing the code to transform the database from its current structure to the new structure which matches the updated models. If the migration can cause data loss, then backup the database and restore the backup under a different name before running update-database, You can then create a script to transform the data from the backup into the new structure of the updated database.
Scaffolded components are a bit different to Entity Framework migrations. Migrations are truly auto-generated classes, and most of the time you wouldn't need to update (or even look at) the generated code. Think of scaffolded components as being more like a kind of template - it's a way of getting started with the classes, methods, markup etc that you're most likely to need, which is quicker than writing it all from scratch. It's not an alternative to writing code though, the intent is that once you've created the scaffolded code, you'll maintain it manually going forward. There is no way (that I know of) to automatically update scaffolded code to match a new model whilst retaining any edits you've made to it. You have two options
Re-scaffold the code and then apply your edits to it
Update the code manually to match the new model
All you can really do is weigh up the two options and decide which one is the least effort.
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.
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.
Now that i have generated 19 code-first classes from an existing database by:
Creating a Model-First Entity, and choosing "Generate from database"
Right clicking and choosing "Add Code Generation Item"
EF 4.x DbContext Generater
All the classes i want are generated, and I'm very happy with them...
And now for my question(s)
Why are they all the generated .cs files nested in a sealed .tt collection?
Why can't i copy paste them out to any folder i like, and treat them like normal classes?
Is it just me, or are you unable to use migrations "update-database" when you do it like that?
I guess my overall question is, why are they located in a .tt folder?
And how shall i update my database now? By editing the database manually and then update the Model, and then generate the dbContext again? Or is there a trick to get .cs files out of a .tt folder?
How do you modify you database after generating your DbContext?
Why are they all the generated .cs files nested in a sealed .tt collection?
Your code-first classes are not code-first classes. They were generated based on your database schema. Hence, this is a database-first approach. With database first, your entity classes are generated based on the database. In other words, the database comes first, the code comes second. The .tt file is a T4 template that decides how to generate your classes based on the database. You could change the database and then regenerate your entity classes.
Why can't i copy paste them out to any folder i like, and treat them like normal classes?
Because they are generated files, based on the T4 template.
Is it just me, or are you unable to use migrations "update-database" when you do it like that?
This part of your question I can't answer for certain, and will have to defer. However it seems to me like you want to mix and match approaches. It sounds like you want to start by generating code classes based on your database, and from there forward, change the database based on new entity classes you add to the model project. Is that right?
You can forgo the code-generation part and just go with a pure code-first approach, now that you have an idea of what the entity POCO's should look like. I have tried this T4 code generation before (pre EF 4.1) and immediately abandoned it, because as you have seen, since the entity and DbContext classes are generated, you lose control over the object-oriented model.
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.