Is it possible to add custom code (hook) to context in order to process queries like this:
var author = context.Authors.Include(e=>e.NotMappedClassField).Where...
Where NotMappedClassField is what it sounds: the class field with attribute [NotMapped]
In other words constract custom fields on the fly by an event.
.Include does not do this. This call operates on related entity types. Using this eagerly loads associated entity types e.g. a one-to-many mapped table. For more examples, read Loading Related Entities on MSDN.
If you are interested in learning how to modify query behavior, you will need to understand how EF6 and EF7 compile and execute queries. There is not simple hook for tying in custom query behaviors that are this different from default behavior. The source code is open-sourced at the links below:
EF6: https://entityframework.codeplex.com/
EF7: https://github.com/aspnet/EntityFramework
Related
I understand the fact that generating a model based on the DataBaseFirst method woill produce a collection of entitites on the ORM that are essentially mapped to the DB tables.
It is my understanding, that if you need properties from other entities or just dropdownlist fields, you can make a ViewModel and use that class as your model.
I have an AppDev course that I just finished and the author wrote something that if I understand it correctly, he is referring to change the ORM entities to fit what your ViewModels would look like, hence, no need for ViewModels. However, if you do this, and regenerate the ORM from the database, those new entities that you placed as "ViewModels" would be gone. If you changed the ORM to update the database, then your database structure in SQL Server would be "undone".
Please inform me if my understanding is correct that I simply need to use a ViewModel in a separate folder to gather specific classes and or properties in a superclass or a single class with the properties that I just need and use that as my model....
Here is the excerpt from the author:
EntityFramework is initially a one to one mapping of classes to tables, but you can create a model that better represents the entities in your application no matter how the data is stored in relational tables.
What I think the author may have been hinting at is the concept of complex models. Let's say, for instance, that in your Database you have a Customer Table and an Address Table. A one to one mapping would create 2 model items, one Customer class and one Address class. Using complex model mapping, you could instead create a single Customer class which contained the columns from both the Customer Table and the Address table. Thus, instead of Customer.Address.Street1 you could refer simply to Customer.Street1. This is only one of many cases where you could represent a conceptual model in code differently than the resulting data in storage. Check out the excellent blog series Inheritance with EF CodeFirst for examples of different mapping strategies, like Table Per Hierarchy (TPH), Table Per Type (TPT), Table Per Concrete Class (TPC). Note that even though these examples are CodeFirst, they still apply to Entity Framework even if the initial models are generated from a Database.
In general, if you use DatabaseFirst and then never modify the resulting entities, you will always have a class in code for each table in the database. However, the power of Enity Framework is that it allows you to more efficiently work with your entities by allowing these hybrid mappings, thus freeing you to think about your code without the extra burden of your classes having to abide by rigid SQL expectations.
Edit
When the Database-First or Model-First entities are generated, they are purposely generated as partial classes. You can create your own partials which extend the classes that are generated from Entity Framework without modifying the existing class files. If the models are re-generated, your partial classes will still be intact. Granted, using partials means that you have the Entity Framework default behaviors as well as your extended behaviors, but this isn't usually a huge issue.
Another option is that you can modify the TT files which Entity Framework uses to generate your models, ensuring that your models are always regenerated in the same state.
Ultimately, the main idea is that just because the default behavior of Entity Framework is to map the database to classes 1:1, there are other options and you are never forced into something that isn't efficient for your project.
I am developing MVC application and using razor syntax. I have used model first method.
I have two entities, Customer and Lead. Lead is inherited from Customer.
When IsActive property is true then Customer treated as a Lead, otherwise it will be a customer.
Please check edmx file image.
Now, In regular entities we just deal with single entity and single table.
In this case how can I handle , Save and Load process. beacuse I have to store and load the record from 2 tables of DB.
Is Regular Index View will work here ?
When using inheritance in the Entity Framework you will have a single DbSet on your DbContext that exposes your hierarchy. In your database you have several options for configuring your table structure. For example you can use:
Table per Hierarchy
Table per Type
Table per Concrete type
(See this blog for a nice explanation: Inheritance in the Entity Framework.
In your queries however, you don't have to think about this. Your queries will have the following structure:
var leads = from l in dbcontext.Leads.OfType<Customer>()
select l;
The OfType() filters your collection to a subtype in your hierarchy. If you skip the OfType you will get both customers and leads in your resulting query.
I have 2 entities (say People and Books) that have two many-to-many relationships. I have created two different linking tables - e.g. the linking tables are called BooksCheckedOutByPeople and BooksOnHoldByPeople.
EF 4.0 correctly makes two relationships. It calls them something like PeopleBooks and PeopleBooks1.
When I am making Linq queries, how do I tell Linq to use a specific one of these relationships? Is there any way in Linq to specify one relationship instead of the other?
Say I'm creating a query against People and I want to get the Books for BooksCheckedOutByPeople and thus I need to use the relationship PeopleBooks.
Thanks.
You should be able to rename "PeopleBooks" and "PeopleBooks1" to more informative property names by editing the model EF generates for you. Something like "BooksOnHold" and "BooksCheckedOut".
At that point, when writing your LINQ queries, just reference the right navigation properties (as they're called). LINQ uses whichever properties you specify, and the Entity Framework should generate a unique navigation property for each collection.
Edit
I just fired up VS2010 to copy your model and poke around a bit.
I see that EF4 did indeed generate two Navigation Properties foor Book and Person, called People and People1, and Books and Books1 (respectively).
If you select any of these Navigation Properties in the Model Browser and look at the Properties pane, you should be able to see which table is correlated to that association and rename the property appropriately. Here's a screenshot from my PC:
You can see that I've selected the "People" nav property for the "Book" entity. The association in this case is determined by BooksCheckedOutByPeople, so I can rename the property to "PeopleCheckingOut", or something more useful than "People". When I'm using LINQ-to-Entities later, I then reference the "PeopleCheckingOut" property to query that collection on any specific Book.
I am constanstly having problems with model design in MVC. Mostly all of my projects require some entities that are to be created, edited and deleted. Most of these entities have some common properties like creation date, modified date, author, modified by and in some cases even more descriptive properties are common. Because of that I have one single DB table to store them. For instance, Documents table and we store Invoices, Quotations and other business documents in it. I am using Entity Framework v4 for ORM, where we eventually end up with the Document entity.
How do I modify this entity or do I create a separate DocumentViewModel class for it to support multiple document types with common properties (so some form of inheritance or interface implementation should be implemented)? Besides identifying different document types I also need to have some types to have different Data Annotation rules (attributes).
For instance, Document table has PayDate column. Document type Invoice requires PayDate to be provided but document type Quotation does not.
This is the one single problem I am facing over and over with MVC and so far I've been handling it different every time but cannot decide how to properly handle it to achieve the maximum application maintainability and ease of development.
Have you considered making Documents entity abstract?
From the DB side, you will have Documents table containing just the fields shared by all Invoices/Quoations/etc. This field will have an IDENTITY PK - e.g DocId.
In the other tables, additional meta-data specific to that document can be stored, and the PK is a (non-IDENTITY) field DocId, which is also a FK to the Documents table.
On the EF side, Documents becomes an abstract entity, and the other entities inherit from this entity. This allows a nice OO paradigm to exist, and makes your code more robust.
We are currently using this scheme (EF4/SQL Server).
Your scenario sounds very similar to ours - consider using Abstract Classes.
EDIT
Thought i'd add a bit more info to how i've actually implemented this scenario, to put you on the right track.
As the comments to your Q state, we have little knowledge of your domain, therefore it's hard to make informed opinions. Personally, i chose to make my entity abstract, because certain functionality required a "mixed-bag" of items to be returned in one hit. There are other ways to do this of course (such as a stored procedure), but this allows a nice fluent interface between my UI (which is MVC by the way) and my service layer.
Works like this - here's how i get a single Post:
// var is strongly-typed to a "Post"
var somePost = repository.FindSingle(10);
Here's how i get a mixed-bag of Posts:
// var is strongly-typed to a "ICollection<Post>".
// "Title" is a property on my "Post" abstract POCO
var mixedBagOfPosts = repository.FindAll<Post>(p => p.Title = "Some Title");
Here's how i get a collection of "Reviews" (child of Post):
// var is strongly-typed to a "ICollection<Review>"
// "Rating" is a property on my "Review" POCO (derived from Post)
var reviews = repository.FindAll<Review>(r => r.Rating == 5.00);
The kicker is my repository is implemented with generics, and the type parameter ensures type-safety:
ICollection<T> FindAll<T>(Expression<Func<T,bool>> predicate) where T : Post
And it's implemented like this:
return myContext.Posts.OfType<T>.Where(predicate).ToList();
The OfType causes an inner join to the T (which is the child table), so only those records are returned.
Of course, i also have a service layer mediating between my UI and repository, but this should get you on the right track.
Also, you don't have to go with the whole Expression-predicate thing, i like this because it minimizes the number of methods on my interface, and gives full querying power to my controllers, whilst ensuring the queries are deferred to the point of the service layer, but not further.
If you don't like this, you could of course have regular parameters (string title, etc).
As i said, this architecture suited my domain requirements, so it may not necessarily suit yours, but hopefully it gives you some insight.
You can put a table in your EF model many times and just rename them to the entities you need. Just delete the columns you dont need from those.
For example, put in a Documents entity... now rename it to Invoice. Now add another one, and name it Quotation... on the Quotation, click on PayDate and hit the delete key. You can customize these all you want! You can do the same with other ORMs, just takes a little more work. With NHibernate you would manually create the Models, then map them to the same table, but only map what you need.
I have a few tables that reference the same table. For example:
Person has an address.
Business has an address.
When using the models I would like to do this in the controller:
person.Address.Zip
business.Address.Zip
I'm coming from a rails background where I can just declare a relationship and have all the above functionality. Force loading of the address when I get the object (person or business).
I'm new to entity framework, and I'm struggling with how to achieve that functionality. I can't include the table in both models (person and business). If I use repository pattern and add the objects to a partial for the class, then I'm using lazy loading.
Am I looking at this wrong? Any suggestions for patterns I could use?
If your using Entity Framework 4.0 with Visual Studio 2010 lazy loading is automatic.
If your using Entity Framework 1.0 your life just got harder...
To eager load with EF1 you have to use the Include() method on your ObjectQuery and specify which navigation properties ( address ). For example:
ModelContainer.Persons.Where(#p => #p.Id == 39 ).Include("Address")
For "lazy" loading you have to manually load all of the FK associations manually. For example:
var myPeople = ModelContainer.Persons.Where(#p => #p.Id == 39
if( !myPeople.Address.IsLoaded() )
myPeople.Address.Load()
Another option is to modify how EF1 generates your model types and include lazy loading out of gates.
http://code.msdn.microsoft.com/EFLazyLoading
Previously, I was creating an ADO.NET Entity Data Model for each controller.
Now I've created one Data Model for all tables (it's not a monstrous db). That way I can include the tables when I query for eager loading.
If anyone has a better suggestion. Let me know. If anyone knows the correct behavior with a large database, please comment. Would you want one large edmx file to represent the database?
Ideally you should be able to traverse the object model to get most of the data you need, starting with a reference to the current user object.