why DbSet<T>.Add() is designed to support tracking - c#

I'm new to EF, just a question on DbSet<T>.Add() tracking feature.
I can understand that DbSet<T>.Update() does need to support tracking because EF needs to check which properties has been changed then generate correct update statement to avoid unnecessary updates in non-modified columns.
But why DbSet<T>.Add() also needs to support tracking? Because when we use .Add() method, we want to add a brand new record into the table in database. Since the data model is new, every property should be included in the Insert SQL statement that will be sent to the database, so there is no points to track the newly created object, EF just need to include all properties to generate Insert SQL.

Related

Inserting a datatable into SQL Server

I currently have a populated datatable, but I'm having trouble inserting it into my existing (empty) database.
I have looked into sqlbulkcopy as well, but haven't had much luck.
Although using Entity Framework I would expect:
_db.TableName.AddRange(dt);
To properly insert the new data from my datatable.
Where am I going wrong here?
You are missing a few steps. First you need to create the table on the database, this is generally done not at run time for lots of complex reasons. Research Entity Framework Code First for more details on how to do this.
Secondly if you truly want to use Entity Framework you will need to convert your data table into a set of objects of the correct type.
Honestly though I would avoid Entity Framework and embed a CREATE TABLE script (or even better define it before you execute) and then use SqlBulkCopy, just note that SqlBulkCopy needs the table defined ahead of time.

Is it possible to use Entity Framework and keep object relations in the code and out of the database

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.

Track changes in my linq2sql datamodel without having entities mapped to DB tables

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.

EF 4.1 Code First - add column

I have my database already set, I want to add a new field to the model, a new column to the table, is there a way I can do this without losing all my data?
Normally if you delete the DB it will recreate everything automatically but I don't want to lose the data.
I'm using SQL Server 2008 as database.
You will need to use EF Migrations to add the new column to your database. You can read more about EF Migrations here and here.
If you're using code first, I've always just added the column to the database manually in situations like that. Unfortunately, there is no simple way to automate incremental model updates with Code First.
For example, one of EF Code First's own errors even specify manual update as the best option:
The model backing the ‘your context’ context has changed since the database was created. Either manually delete/update the database, or call Database SetInitializer with an IDatabaseInitializer instance. For example, the DropCreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data.

View using same type as Table

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!

Categories

Resources