I have a table that used throughout an app by Entity. I have a view that returns an identical column set, but is actually a union on itself to try to work around some bad normalization (The app is large and partially out of my hands, this part is unavoidable).
Is it possible to have Entity 4 treat a view that is exactly like a table as the same type, so that I can use this view to populate a collection of the same type? This question seems to indicate it is possible in nhibernatem but I can't find anything like it for entity. It would be an extra bonus of the navigation properties could still be used to Include(), but this is not necessary (I can always manually join).
Since EF works on mappings from objects to database entities this is not directly possible. What you need is something like changing the queried database entity dynamically, and AFAIK this is not possible without manually changing the object context.
For sure the EF runtime won't care as long as it can treat the view as if it was completely separate table. The two possible challenges that I forsee are:
Tooling: Our wizard does allow you to select views when doing reverse engineering (i.e. database-first). Definitively if you can use 'code first against an existing database' you can just pretend that the view is just a table, but you won't get any help scripting the database creation or migrations.
Updates: in general you can perform updates for a view setting up store procedure mapping (which is available in the EF Designer from v1 or in Code First starting in EF6). You might also be able to make your view updatable directly or using instead off triggers (see "Updatable Views" here for more details). If I remember correctly the SQL generated by EF to retrieve database generated values (e.g. for identity columns) is not compatible in some cases with instead-off triggers. Yet another alternative is to have your application treat the view as read-only and perform all updates through the actual table, which you would map as a separate entity. Keep in in mind that in-memory entities for the view and the original table will not be kept in sync.
Hope this helps!
Related
I'm having a hard time just defining my situation so please be patient. Either I have a situation that no one blogs about, or I've created a problem in my mind by lack of understanding the concepts.
I have a database which is something of a mess and the DB owner wants to keep it that way. By mess I mean it is not normalized and no relationships defined although they do exist...
I want to use EF, and I want to optimize my code by reducing database calls.
As a simplified example I have two tables with no relationships set like so:
Table: Human
HumanId, HumanName, FavoriteFoodId, LeastFavoriteFoodId, LastFoodEatenId
Table: Food
FoodId, FoodName, FoodProperty1, FoodProperty2
I want to write a single EF database call that will return a human and a full object for each related food item.
First, is it possible to do this?
Second, how?
Boring background information: A super sql developer has written a query that returns 21 tables in 20 milliseconds which contain a total of 1401 columns. This is being turned into an xml document for our front end developer to bind to. I want to change our technique to use objects and thus reduce the amount of hand coding and mapping from fields to xml (not to mention the handling of nulls vs empty strings etc) and create a type safe compile time environment. Unfortunately we are not allowed to change the database or add relationships...
If I understand you correct, it's better for you to use Entity Framework Code First Approach:
You can define your objects (entities) Human and Food
Make relations between them in code even if they don't have foreign keys in DB
Query them usinq linq-to-sql
And yes, you can select all related information in one call.
You can define the relationships in the code with Entity Framework using Fluent API. In your case you might be able to define your entities manually, or use a tool to reverse engineer your EF model from an existing database. There is some support for this built in to Visual Studio, and there are VS extensions like EF Power Tools that offer this capability.
As for making a single call to the database with EF, you would probably need to create a stored procedure or a view that returns all of the information you need. Using the standard setup with lazy-loading enabled, EF will make calls to the database and populate the data as needed.
I am using VS 2013 Express for Web with ADO.NET Entity Data Model.
When updating the entity data model from database using 'refresh' tab option (seems you can only select one item though the heading says select objects plural) the usage seems unclear and I have noticed some issues.
Just two examples:
I changed a stored procedure so it returned the same number of fields but one field was of a slightly different type but the complex type never changed. I realise there can be an impact on client code but this simply did not change the complex type, everything stayed the same. However, removing the relevant elements from the model browser then readding the elments from the database back into the model did exactly what I expected.
I made some significant changes to two or three tables, attributes and one relationship but did bot change the table names. Here again refresh had some very odd results, so I simply created a fresh model.
I am planning some more changes first change specifically I am adding a FK relationship that I forgot.
Is there any way to be sure of what is supported and what is not in terms of refresh.
Also I am concerned that if refresh fails and I so delete the two tables with the relationship, what impact will that have on temporarily orphaned tables and their relationships, and if when I regenerate the two tables their connections with the other tables will still work. I guess it depends how the generated code works underneath.
I want to make these kinds of changes but avoid have to recreate the entire model.
Any advice appreciated.
The most guaranteed way of ensuring you always have the latest version is to select all (Ctrl A) delete, and then re-add everything from the model page.
I know it sounds like a pain but it's guaranteed to work as long as you haven't made any changes to the model from within Visual Studio.
The refresh doesn't always work.
I'm trying to use linq-to-sql, and this is all very new to me.
I am creating objects, that doens't translate to actual tables, in my database. In essence, I have some objects, that get values from 3 different tables, and I select them with stored procedures.
It works great.
However, when I need to submit my changes, I assume SubmitChanges() will not work, and I will need to make my own save functionality.
But how do I see what have actually changed? If I call GetChangeSet() on my datacontext, it says nothing has changed, even though the model has been changed.
Do I need to track the changes manually? If so, are there any tricks or practices I could use?
LinQ to Sql tracks that changes via auto-generated code. You can see it by hitting F12 on linq-to-sql generated object types.
Also, you could study it and make your objects to save changes inside datacontext (which is also a unit of work) the way the generator does.
Assume that I have a entity data model I generated from my database. I use one of the columns throughout code in many places, but one day I decide that I don't need this anymore, so I remove it from the database and the places in code that reference this property from the entity data model are now broken. Is the only solution to this is to go to each place and fix it or are there any strategies or tools that can assist in scenarios like this?
This question is only practical for applications that haven't been released yet. If an application has been released and this column already exists, it would not be removed or deleted. Existing customers may be depending on that column for data, it may be tied to application logic etc. For compatability reasons, it wouldn't be removed.
If this is pre-production application (pre 1.0 release), any ORM solution should be able to recreate the logical and conceptable model(s) after the physical column in the database has been removed. At that point, there may be some cleanup in the other layers of the application (UI, business, etc) that reference conceptable model in some fashion. For example, the UI may need to be updated to remove the display of that data. That would require some manual effort.
In general, it is better to keep it unless the application is in the early stages of development.
As such, you haven't specified about data in column and need for removing it, so we have to talk in general terms.
If you can remove the column from database and yet has used it in many places at code then probably its computed column - In general, it means you can derive the same information from other data-points. So in your entity model, you should stop mapping the column to the database and rather replicate the logic in the code to compute meaning-full value for the property. Or you can create a view over the table and compute the column at database side and map your entity to the view instead of table.
In case, the column is not computed then removing the column from database means loss of data. And if that is acceptable then it essentially indicates the change in underlying business model where that data point become irrelevant. You have two choices here -
Go for it and change your code for not to use this property - it essentially means that you will adjusting your code for business model/process change that you have to eventually do at some time.
Keep the column in database for some time but have a meaning-full default value. Mark the entity model property obsolete so that it will start giving warning. Take your time to make code changes, ultimate aim is to remove the property usage over a time and then remove the database column.
We have a big (and growing!) database. We're trying to not have to build the models by hand, and we found this
EdmGen2 which is supposed to build our EDMX entity models for us.
Since we have such a big database we'd like to not have all of our tables in the same Model. We got it all to work, but the generated model has all of our tables.
There is a read only list of the tables inside of the EntityStoreSchemaGenerator. It is (in fact) all of our tables.
Will this tool make a model that is less then our full database? Can we select which tables we want to put it and only use those?
The EdmGen2 code comes with an option called /RetrofitModel. The key point of this mode is that is runs some data mining algorithms to see if there are any obvious inheritance-like relationships in the database instance, and if so, generates an EDMX that includes those inheritances.
However, another feature of the /RetrofitModel option is that it allows one to select tables. For instance, if one has the AdventureWorks sample database, you can issue this statement:
EdmGen2 /RetrofitModel "Server=(local);Integrated Security=true;Initial Catalog=AdventureWorks;" "System.Data.SqlClient" "AVWorks"
It will bring up a list of the tables in the database, at which point you can check which ones you want to have in your model.
The tupleFraction parameter helps define what it means to be a "significant" subclass. The data mining rules are heuristics, and as such they can potentially find patterns where common sense might not agree.
The tupleFraction parameter says this (for some of the rules): if EdmGen++ thinks that it has found a subclass, but the new subclass has less than tupleFraction of the instances from its parent class, consider the new subclass "insignificant" and don't create it. The parameter is optional - if you don't specify it, I think that it gets set to 0.05 (5%).
The current version only allows table specification through the UI. However, to pull the list of tables from a file or from some other source is an easy addition - I will add it to the top of the to-do list for the next version.
UPDATE: We have updated the code at code.msdn.microsoft.com/edmgen2 to allow for tables to be specified without the GUI. In the previous version, the RetrofitModel option would bring up a dialog that would allow the user to choose the tables to include in the model. The ConceptualEdmGen dll now has two additional public methods that can set the list of tables without bringing up a dialog – one that pulls the list of tables from a file, and one where the list of tables is fed directly to the method as a list of strings.
The EdmGen2 code as it appears in the package uses the “from file” option, where it looks for a file called “Tables.txt” in the current directory, and if found, feeds its contents to the dll to set the list of tables. So for instance, if the following were the contents of the file “Tables.txt”:
HumanResources.Department
HumanResources.Employee
HumanResources.EmployeeAddress
HumanResources.EmployeeDepartmentHistory
HumanResources.JobCandidate
HumanResources.Shift
EdmGen2 would generate (for the RetrofitModel option) a model for all of the tables in the HumanResources schema for AdventureWorks. For both methods, an empty list will result in all tables in the database being added to the model. The table selection UI will still appear if neither table selection method is called.
I've just sent an email to the guy responsible for EdmGen2 lets see what he comes back with
Alex James
Program Manager, Entity Framework Team, Microsoft.
My solution to this was to create a variant of EdmGen2 which reads a Filters.txt file that contains not just table names, but text that gets parsed into EntityStoreSchemaFilterEntry parameters (Category, Schema, Name, ObjectType, FilterEffect). This allows me to generate models and assemblies which operate on specific views as well as tables - something that I don't think EdmGen2 does.
Of course that doesn't work with the ConceptualEdmGen, but since there is no source available for that I've elected not to use that component anyway.
One problem that I haven't solved is how to properly inject function definitions for stored procs into CSDL and MSL. I have it in SSDL but don't know yet how to do the others.