Partial saves in Entity Frameworks 4.1 - c#

I'm pretty new to Entity Frameworks.
I have a set of Static Data which includes the following:
Templates, which have a Many To Many relationship with Columns
I want to create a new UserReport which has a reference to an existing Template, and a subset of the Columns associated with the said same template.
I expect to save the UserReport record, and a series of records in a UserReportColumns mapping table linking the UserReport to existing columns.
My code is as follows:
ReportTemplate template = staticData.ReportTemplates.First();
UserReport newReport = new UserReport()
{
....
Columns = FilterColumns(template.Columns)
....
}
....
context.UserReports.Attach(userReport);
context.UserReports.AddObject(userReport);
context.SaveChanges();
This attempts to recreate everything in the object hierarchy in the database.
How can I get it so that it only saves the UserReport and the UserReport_Column links?

You are retrieving the template from a different DbContext instance(or some cached data source). Hence the context assumes that the template and the columns are new objects.
To overcome this problem you have to attach the existing objects to the context to avoid EF adding them to the database.
foreach(var column in newReport.Columns)
{
context,Column.Attach(column);
}
context.UserReports.Attach(template);
context.UserReports.AddObject(userReport);
context.SaveChanges();

Related

Inserting Disconnected Related Entities with Entity Framework 6

I have some data from an XML file that I have transposed and I can map to my Entities. So now I want to save them all to the database .
I was reading on SO Can Entity Framework add many related entities with single SaveChanges()?
The accepted answer does not have too much info but this statement:
'You don`t need to save changes every time if you use objects
references to newly created objects not IDs:'
My entities are derived from a dataset tables which all have a related Id columns.
And I guessing the answer is more or less that the related entity was created with something like this : item.SubItem = new SubItem();
rather than item.SubId = SubItem.Id;
So should I traverse my data tables and translate my dataset tables into Entities by creating the objects from the tables and adding them to the context.
So for each row in dt['Items'] if row has a subitem new SubItem {all values except the Id}..??
Any example code would be appreciated.
So after working to resolve the issue I discovered if I create a new object of my entity and map values to it excluding the ID column I can then assign this object back to the parent.
pseudo code is below:
myobject = new myobject(){ param1 = oldobject.param1}
myentityParent.ChildTableEntity.Add(myobject);

Including a new table in the DBContext made with CodeFirst

We have a Data library they have built it with CodeFirst.
Now I ran a SQL command and added a new table to that database.
But Now I want to also see its generated object class, its DBContext definitions ,etc.. in the code first code so I can use them in my LINQ queries.
So what I did was following number 3 method from this MSDN page:
https://msdn.microsoft.com/en-us/library/jj200620.aspx
But it didn't do it right. For example it did not add any definition for this new table to DBContext.cs file, for example all my other tables that used to be there are defined like this:
DbSet<Zipcode> Zipcodes { get; set; }
But it has not added anything for me.
What is the correct way to do this?
I'm unaware of a way to simply add a new table and have it 'plug-n-play' with your existing model without manual work. The two options I know of are:
Rebuild the model using Code First from DB and include your added table
Manually create the table as a class and add the DbSet and entity in the OnModelCreating method in your model
Code First from Database only works when you already have a database. If you want to add a new table, you will have to start using Code-First(alone), that means: add the entity Zipcode to the model, DbSet to the DbContext and after that when you compile it will generate de table in the database.

Problems in handling EntityFramework objects

(Using: Visual Studio 2010, SQL Server 2012, Entity Framework 4.0, MVC3 web application)
I have tables with one-to-many and many-to-many relationships, I used (database first) to automatically generate model classes, meaning I have objects inherited from EntityObject and the base class inherited from ObjectContext.
I am having trouble with (inserting, updating, deleting) objects.
For example when creating an object: I have a many-to-many relationship between 2 tables (Area and Cell) and the middle table (CellArea), and I want to add a new Cell object which is connected to many areas, so I did the following code:
Cell _cell = new Cell()
foreach (Area ar in current_areas)
{
var ca = new CellArea();
//ca attributes
_cell.CellAreas.Add(ca);
}
db.SaveChanges();
db.Cells.AddObject(_cell);
db.SaveChanges();
I tried other code snippets and none of them worked, I always get IEntityChangeTracker and other similar exceptions.
What is the proper way to manage such cases?
When there are intertable relationships EF should create what is known as navigational properties. When you perform the initial query you can either choose to have those properties loaded or not. In particular EF has a keyword named Include that allows you to populate those other properties at will. If all the other date is included and any changes are made, you only have to call the SaveChanges method and the original table data and all navigational property data is saved in one shot.
Google "EF Include"

How to find the mapping tables in from the EF generated Classes

I have a mvc 4 application which is entity framework database first based. Therefore lots of the classes are generated based on database tables via EF.
Currently, I created a method to retrive data from a table and display them in a dropdownlist, which works fine. However, I am thinking to modify that method to a generic type method, and passing the class type as the method parameter, and I would like c# code to find the mapping table in the database and retrive the data.
Following is my modified method
Thanks for your helps!
public static SelectList FromDbTableToSelectList<T>() where T: class
{
var db = new TableEntities();
//find the mapping database table
Dictionary<Guid, string> dic = db.MappingTable.ToDictionary(v => v.tableColumn1, v => v.tableColumn2);
return new SelectList(dic, "Key", "Value");
}
I don't understand your what your code does. However, there is a trick to find mapping table name (Entity Set Name in EF glossary) of an entity.
Suppose that you have a table in your db named Products. If you create your model with the Pluralize and singularize option checked, EF will create an entity class named Product.
Then, whenever you perform a query, EF naming convention thinks that your table name is dbo.Products. This is a general rule - in fact a naming convention.
From the other hand, if you uncheck the Pluralize and Singularize option, EF creates an entity class named Products for you and in this case, the class an the table have same names.
So, according to the selection of P&S option, you can infer table names from entity names and you don't need any code for it...

Accessing a Common Code Value Table in Generated EF Models

I have a database that uses a custom model for recording lookup valus (i.e. states, types, etc.). So across all of the database tables, there are various columns called something like state_cdv_id which would store an integer and reference the code_value table to get that state's value (i.e. "CA", "AK", etc.).
I would like to map my EF model so that I can access the code values for all of these fields, and I don't want to have to do it manually in partial classes for EVERY entity... that's a lot of repetition. So I want to be able to access my code values like: MyPerson.State and get back the string "CA" for example.
Here's what a single getter would be that I would have to repeat many times if I were to do it manually:
public string State
{
get
{
MyEntityContext c = new MyEntityContext();
return c.CodeValues.Single(cv => cv.Id == RecordStatusCdvId).Value;
}
}
I don't know what the best approach would be: change the T4 templates, add property attributes to certain fields and then programmatically add a getting to those, or something else.
Any help?
If there is a 1:1 relationship between the entity and the code_value table the entity should already have a State property, which by default which will be null by default, you could then fill it in by using an Include on your DB queries:
var foo = context.MyEntities.Include( x => x.State);
Your sample code is terribly wrong because it makes your entity dependent on the context (moreover you don't dispose it). Whole POCO approach just to avoid this (POCO T4 generator and DbContext T4 generator).
If you have relation to lookup table in your database EF will crate for you navigation property. If you don't have such relation in the database and you are using EDMX file you can still create such relation in your model and you will again get navigation property to lookup table. Once you have navigation property you can simply do:
string code = myEntity.State.Code;
But the navigation property must be loaded either by eager loading (as #BrokenGlass described) or by lazy loading.
If you don't like the idea of navigation property and you still want State property to show just code of the state you must understand what does it mean: If you map the entity that way it will be read-only because EF will not be able to transform compound entity back to real tables which must be updated. It is possible to map the entity the way you want but it is considered as advanced (and mostly not needed) scenario which works only if you have EDMX file (not with code first approach). The choices are:
Create database view and map the view to a new entity
Create DefiningQuery manually in EDMX (opened as XML) file and map it to a new entity (once you do that you cannot update your model from database or generate database from model any more)
Create QueryView manually in EDMX (opened as XML) file and map it to a new entity (this requires original entities to be already mapped)
You will have to do that for every table where you want such mapping. Anyway whole that complexity with manually changing EDMX is not needed because you can simply create custom classes like:
public class SomeViewModel // I suppose your main target is to have codes in presentation layer
{
public string SomeData { get; set; }
public string State { get; set; }
}
and use projection query
If you have navigation property:
var data = from x in context.SomeEntities
select new SomeViewModel
{
SomeData = x.SomeData,
State = x.State.Code
};
If you don't have navigation property
var data = from x in context.SomeEntities
join y in context.LookupValues on x.LookupId equals y.Id
select new SomeViewModel
{
SomeData = x.SomeData,
State = y.Code
};

Categories

Resources