I am developing a web-based system using .NET MVC and Entity Framework, from a legacy system. I will keep the legacy database and only develop the application, so I will create entity classes using database first approach.
My concern is, in the entity classes, I will be adding attributes such as filter attributes. And I may add some extra fields there as well. Will the database be updated automatically? I actually don't want to update the database at all. I only want extra stuff stay with the entity class only.
You can easily create your database first and then start working on the backend side of your application as you would do it in an "Code first" approach.
I'd recommend reading this article, as you might get all your answers cleared with some examples: Entity framework
First, when adding additional properties in your entity classes you will want to mark them for EF to ignore using either the [NotMapped] attribute or in your DbContext class calling .Ignore on the property. Not Mapped Attribute
Second, in terms of EF changing your database you can do a couple of things.
1. Ensure the account that is updating data does not have Create,Alter,etc permissions in the environment
2. Use a null database initializer at the beginning of your application. Database.SetInitializer(null); Setting the initializer to null tells EF not to make any sort of changes to the database. Turn off DB Initializer
Maybe you should consider using partial classes.
I find editing anything in EF quite hard.
EF Classes from your DB are all :
public partial myClass(){
public string myDBProperty;
}
Which means you are able to create a second class in the same namespace like :
public partial myClass(){
public string myOwnProperty;
}
Related
I want to add an existing database to my project, but it doesn't respect the schemas in.
On my project I do:
Add new file -> data -> ado.net entity data model -> EF designer from database -> .... -> and I select the tables I want.
The tables look like this: Image from sql manager
And they are imported like this: Image from visual studio
Is there any way to make EF generate entity data model classess with naming structure like [schema.name], e.g., Stock.Equis?
C# does not allow '.' character in class names so the naming structure that you are looking for is not possible.
If you still want to have some kind identifier in class names for schema then you might be able to find work arounds but I would suggest not to do so because if you make this kind of customization here then to adapt to this customization you will have to develop several work arounds with many future code as your project grows. This kind of customization may also make code look inconsistent, cause readers difficulty in understanding the code because this convention has been followed by Entity Framework for over a decade now, cause maintenance problems and might also violate C# best practices. Therefore I suggest, play along and stick with the default implementation. I personally always stick with default implementations and I have never faced any complications.
Following is a short article on working with Schema Names in Entity Framework. This may be helpful to get the idea on how to link Schema Name with Entity Data Model classes. This article is for Code-First approach but you should be able to grasp the concept for Database-First approach as well.
https://www.itprotoday.com/development-techniques-and-management/working-schema-names-entity-framework-code-first-design
You must to use an annotation for this.
using System.ComponentModel.DataAnnotations.Schema;
[Table("StudentMaster")]
public class Student
{
public int StudentID { get; set; }
public string StudentName { get; set; }
}
Reference: https://www.entityframeworktutorial.net/code-first/table-dataannotations-attribute-in-code-first.aspx
I am currently writing a .NET MVC application using a SQL Server DB and Code First EF. All has been going great and stackoverflow has been extremely helpful. Unfortunately I have an issue I cannot solve and I can't find any help on the Internet.
I want to integrate with PayPal and I was following http://logcorner.com/asp-net-mvc-paypal-integration which seems fairly straight forward except that VS wants to create a database table for my PayPal model and I don't need or want it to. I have added [NotMapped] in front of the class but now it generates this error:
The type 'MyApp.Models.PayPal' was not mapped. Check that the type has not been explicitly excluded by using the Ignore method or NotMappedAttribute data annotation. Verify that the type was defined as a class, is not primitive or generic, and does not inherit from EntityObject.
I saw some other information about adding Ignore(lambda expression) in the OnModelCreating() method of my db context but that seems to be for excluding a column, not the entire class.
Any ideas? I don't want a database table for every model in my application.
By Default all the model will be created in database which is the part of your myAppEntities : DbContext class and which properties type is DbSet<>.If you have decorated your model MyApp.Models.PayPal as notmappedattribute.
[NotMapped]
public class PayPal
{
//your all properties
}
Then remove Dbset<PayPal> properties from your class which is inherited form DbContext Class.
public class MyAppEntities : DbContext
{
public DbSet<PayPal> paypal { get; set; } //Remove this or comment this line
...
...
//rest of your properties
}
By doing so this won't be part of your database and you wont get this error.
( Explanation of this thing will cover a whole topic which i can't explain here).
Your usage of the [NotMapped] attribute is correct offhand. The issue is either that (a) you're attempting to scaffold while this attribute is in force, or (b) you're attempting to access the db in relation to this type at run-time. That's when I saw this error during my test work (see later).
At the design end, the following would solve your problem if you are using auto-scaffolding (but see later):
Delete or comment out [NotMapped] on your PayPal-facing class.
Recompile. (Due to latencies in MVC's introspection into the code,
your past attribute will still be in force until you do this.)
Now do your scaffolding.
Now uncomment or re-add [NotMapped].
Recompile again for the same reason as before.
There isn't much reason to auto-scaffold if that is where you're having problems, as you don't want to save your data so you don't need CRUD ops. The example on your refsite uses nearly-empty controllers compared to what the IDE generates for you.
At the run-time end (that is, in your controller code), just make sure you never touch the db. Definitely nothing like db.SaveChanges(); You shouldn't need to as I was saying; this is really a ViewModel and it exists solely to push data to PayPal.
To verify the problem and solution, I created an example MVC app, got the message you saw, took the design-time steps, then ran the app in a browser, got the problem message again, removed the db-facing code from my unmapped-class controller, and was able to have things work properly. I didn't use the PayPal-facing class but a simpler one to save time, but there should be no difference in outcome.
I hope this resolves your problems. --Ed
This answer describes a way at runtime to "add" properties to a class by creating a base class of the class you want to add properties to.
https://stackoverflow.com/a/14724876/2437521
Would it then be possible to map this class that was created with reflection to a table or view in Entity Framework (in the OnModelBuilding method most likely)
Before people say "That's a dumb idea" let me tell what I'm trying to accomplish. We have a data provider that's compatible with multiple DBMS platforms and using EF as a single code path for this compatibility. We need the ability to use Entity Framework to map to a view in the database to do things like filtering, etc.
This is easy and EF can do these things without trouble. Here's where the problem is. There's a requirement that we be able to join in custom columns into this view and be able to search, sort, filter etc. on these custom columns.
I immediately thought, drat, EF can't do this so I made the method for querying this view just access the vanilla ADO.NET provider underneath and just wrote almost 1000 lines of code with platform agnostic SQL.
Here are the problems I can think of that need to be solved to get this runtime configuration of Entity Framework to work:
Make EF Model Builder map to the Emitted class generated at runtime.
Use reflection somehow to create an Expression that can be used to pass into the IQueryable extension methods
Assume that EF will work with these Expressions and actually generate the SQL needed.
The EF code is something that exists in our core product and it can't be recompiled once it's deployed, hence why I'm trying to accomplish this all at runtime.
Assumptions
Using EF 6.1, MVC 5, VS 2013, C#
I have an existing database model designed in Toad DM for SQL Server and it's very important keep it always updated
Steps and Notes
Using ADO.NET Entity Data Model I chose Code First from Database (new feature in EF 6.1) to generate the models. Note: Model classes and DbContext class generated successfuly but NO .edmx or .tt file was generated.
Next I added a new scaffold item: MVC 5 Controllers with views, using Entity Framework. Note: Success, controllers and views generated
Question
From now on I don't want to use Code First to update my database. Instead I want the models to be updated based on database changes. What to do next? If I don't have an edmx file will I not be able to update my model classes from the database?
The Entity Data Model Wizard's Code First from Database does an excellent job creating your entity classes, as if they were created in the Code First style. What you are asking is if there is any way to keep these classes up-to-date as your database changes, similar to the EDMX style "Update Model From Database". From what I've researched this is not possible using the built-in tooling. However, here is one workaround that I've found useful:
Let's say I have database with a product table and customer table. Originally I created a StoreDBContext class, and selected product as one of my objects. Now I want to add the customer table as a new entity to the existing context. Here's how to do this using the Code First Wizard:
Create a new Entity Data Model, call it StoreDBContextTemp or whatever
Choose the code first from database wizard option
Select customer as an object to add (just customer) & complete the wizard
Open the newly created context file, StoreDBContextTemp.cs, and copy the virtual properties of your newly added entities:
public virtual DbSet<Customer> Customers {get; set;}
Paste these new properties into your Original StoreDBContext.cs dbcontext class.
Delete StoreDBContextTemp.cs, and remove the connection string for StoreDBContextTemp in app.config/web.confg etc.
You can now use Customer on the StoreDBContext class
If you add or remove tables you will need to manually adjust fields, but at least you won't need to hand write dozens of properties each time a new table is added to the model.
One more option is just delete the auto generated classes from the project and once again generate them.
While following this approach only thing we need to make sure that is we should give the same name for the data model(class name which inherits from DbContext ) as the previous one.Data model name is highlighted in below snap
Three things.
There's no .edmx when you use Code First.
If you use Code First Migrations you would have to write first the code and after that migrate the changes to database. This helps you to have much more organized you code with no generated code which is an advantage.
There's a plugin in Visual Studio for doing contrary. Entity Framework PowerTools allows you to select the database and map it to objects.
https://visualstudiogallery.msdn.microsoft.com/72a60b14-1581-4b9b-89f2-846072eff19d
The best solution to me is deleting the model and recreate updated one with the same name, keeping in mind two points:
Personal extension methods implemented for the model;
Possible manual relationships between tables added to the model because of not setted up in the phisical db.
My personal solution:
Move all extension methods to another partial class that won't be overrided;
Insert all added properties of an entity to another partial class;
Keep track of all manual relationships in an help file, so you can add them again being sure not to loose anything;
Delete the old model and recreate one new with the same name and update it with the manual relationships of point 3.
I am delving into the EntityFramework 4 code first of entities approach and I am getting stuck on how to take the ObjectContext / Entities and link them to a database.
I have looked at varous sites on [msdn][1] and [blogs][2] about how to use all of this but they all fail in talking about how to create a database that the entities will be saved in or don't take the code first apprach. I know I can create an edmx file and generate sql from that but since I am writing my entities first this file is empty and through the designer I don't see a way of adding my entities without duplicating effort (in creating all the entities/fields etc).
There does not seem to be the EntityConfiguration class in the full release of entity framework. It appears to be only in the CTP that I am NOT using (a lot of the examples on the web use the CTP).
Also the following context takes strings that in no way seem to relate to the edmx or database.
public class EntityContext : ObjectContext
{
public EntityContext()
: base("name=ExampleEntities", "ExampleEntities")
{
ContextOptions.LazyLoadingEnabled = true;
Users = CreateObjectSet<User>();
}
public IObjectSet<User> Users { get; set; }
}
So the question is.
How do I create a database schema that maps to my entities?
Should I use an edmx file at all or create my own database file (.mdf)?
If I do use the edmx file how do I add my code first entities easily?
How do the ObjectSets within the ObjectContext map to the database?
Thanks
EDIT
I am using VS2010 professional and the classes that come with that. I see CTP4 is out so I assume the RTM version is not out yet. Is this correct?
Add this to your application_start event to create the database:
Database.SetInitializer<YourObjectContextClass>(new RecreateDatabaseIfModelChanges<YourObjectContextClass>());
Looks like I needed CTP4 found here
I also followed the walkthrough