问题
Is it possible to create a view of an entity in entity framework without creating a view in DAL?
i have a parent table named Receipt. Receipt can be active or inactive. if i implement IsActive as an attribute of the Receipt, there's a high risk of forgetting to attach .Where(r=>r.IsActive)
to all Linq queries and high cost of adding it to previous codes. i tried to inherit a child DeletedReceipt with condition IsActive=false in model and add condition IsActive=true to Receipt (Parent). Happily business didn't take any change. the problem is i can not write Deactivate method while Receipt have many important relations. and i know it's not object oriented. i think i can handle it with a view. but i don't change my DAL for a business method!
the case is "IsActive" plays Discriminator role, and is not updatable in Deactivate method. one way may be using SP but that means "DAL please handle my damn Business Logic".
any idea?
回答1:
There are two ways to create view:
- DefiningQuery - custom SQL select in SSDL part of EDMX file. You can use any SQL to define new read-only entity. The problem is that once you use this you cannot use update from database any more because it would overwrite your changes in EDMX (unless you buy some more powerful extension for EF designer).
- QueryView - custom ESQL select in MSL part of EDMX file which must select from existing entities. It supports relations but only to other query views.
In both cases created entity is a view = read-only. You cannot use it for saving changes unless you map update, insert and delete operations to stored procedure or custom SQL (again written in EDMX file).
Anyway what you are trying to do will lead to a lot of problems. Do you ever need to access DeletedReceipt
in your application? If yes do you need to have full logic as you have with ActiveReceipt
? If no don't do this.
The problem is that IsActive
condition for soft delete is something EF doesn't handle very well. You can solve the issue for your main query where you don't need to use Where(r => r.IsActive)
but do you ever use eager loading or lazy loading to load related receipts for any other entities? If yes do you expect to load only active receipts? Here comes the real problem. Neither eager or lazy loading support filtering so you will always load both active and deleted records. The only way to handle this (without doing everything manually) is conditional mapping but conditional mapping allows you to have only one of these entities in your application and you need custom stored procedure for soft deleting.
"DAL please handle my damn Business Logic"
As a side note to this quote if you don't want DAL to handle any logic don't expect it to give you only active receipts automatically. That is a logic in DAL as well. So if you really mean that using Where(r => r.IsActive)
in all queries is what you are looking for. If you want to have some help from DAL it must contain some logic and sometimes the logic would be in SQL.
来源:https://stackoverflow.com/questions/8677981/creating-a-view-of-an-entity