Updating entity with another entity in C# Entity Framework - c#

I have a bunch of entities that need to be updated to match entities of the same class in a different database. For example:
Database1 TableA:
Id| User | FirstName| LastName
1 | Geekguy123 | Fred | Smith
Database2 TableA:
Id| User | FirstName| LastName
34| Geekguy123 | Frederick| Smith
How can I update database1 for Geekguy123 so the new FirstName is Frederick? The ids are different but the User is unique.
To be clear, there are dozens of properties on the entity, which I don't want to update manually. Maybe SQL would be easier?

Just query in database 1 for the record you want. Get its FirstName property and then query the record in database 2 and then update firstname field with the one you got from database 1. And then submit your change.
Db1Context c1 = new Db1Context();
var userToUpdateWith = c1.Users.Single(u => u.User == "Geekguy123")
Db2Context c2 = new Db2Context();
var userToUpdate = c2.Users.Single(u => u.User == "Geekguy123")
Since you got to set many properties, you can do the following.
string[] properties = new string[]{"FirstName","LastName"};
foreach(var property in properties){
object value = userToUpdateWith.GetType().GetProperty(property).GetValue(userToUpdateWith, null);
userToUpdate.GetProperty(property).SetValue(userToUpdate, value, null);
c2.SaveChanges();

Here you go - the pass-through SQL that you can use.
If the table name is really Database1, then replace Table1, Table2 accordingly.
UPDATE t1
SET t1.FirstName = t2.FirstName
FROM Database1.dbo.Table1 AS t1
INNER JOIN Database2.dbo.Table2 AS t2
ON t1.User = t2.User
And the passthrough would be like this:
using (var context = new YourDataContext())
{
context.Database.ExecuteSqlCommand(sqlString);
}

Turns out, there were actually a couple hundred properties. I ended up deleting and re-adding the entity with the new values.

Related

Insert in the link table many to many in Entity Framework

I have 3 tables
Operator
OperatorWarehouse
Warehouse
| Operators | | OperatorsWarehouses | | Warehouses |
| OperatorID | - | OperatorID | - | WarehouseID |
| EmployeeID | | WarehouseID | | Warehouse |
So basically in my entity framework the "OperatorsWarehouses" table does not appear...
There is already data in the Warehouses table, I only need to insert in Operators and OperatorsWarehouses to make the relation.
This is my code
using (InventoryContext db = new InventoryContext ())
{
Employee employee = new Employee();
employee.EmployeeID = Convert.ToInt32(ddlOperators.SelectedValue);
var operator = new Operator();
operator.EmployeeID = employee.EmployeeID ;
db.Operator.Add(operator);
db.SaveChanges();
ddlOperators.DataBind();
}
I already tried
operator.Warehouses.Add(new Warehouse());
But that is going to insert in the warehouses table and i don't want to do that, I want to insert only the operator on that table
You Should Provide the Id for Warehouse of the Operator , if the Warehouse you are adding has 0 as its id then it's considered a new Warehouse.
you can add a dropdown list for the warehouses in your UI that the user selects once they are adding an operator.
using (InventoryContext db = new InventoryContext ())
{
Employee employee = new Employee();
employee.EmployeeID = Convert.ToInt32(ddlOperators.SelectedValue);
var wareHouseId = Convert.ToInt32(ddlWarehouses.SelectedValue);
var operator = new Operator();
operator.EmployeeID = employee.EmployeeID ;
operator.Warehouses.add(new Warehouse(){Id=wareHouseId});
db.Operator.Add(operator);
db.SaveChanges();
ddlOperators.DataBind();
}
Add [NotMapped] in your defintion table :
Something like this
[NotMapped]
public List<Warehouse> Warehouses;
Entity framework will hide the relationship table when it's a "pure" many to many relationship. So you won't be seing the OperatorsWarehouses table, it will be handled by EF.
To add relationships you just add entities to entities, so you can add an operator to a warehouse or you can add a warehouse to an operator.
In your specific case you'll need to add an existing warehouse to the operator, or an existing operator to the warehouse. Something like this:
int whId = 1; //warehouse with id 1
db.Warehouses.FirstOrDefault(x => x.WarehouseID ==
whId ).Operators.Add(operator);
note: be careful about the FirstOrDefault which will return null if there's no warehouse with id 1

Join 3 tables and databind to a ComboBox

Good morning SO.
I have 3 tables (Sql Server) with this layout:
GenreMovies: | RowID | MovieGenre|
GenreMusic: |RowID | MusicGenre |
GenrePodcast:| RowID | PodcastGenre|
I have a combobox/dropdown that I am trying to populate with a Query:
var infoQuery =
(from MovieGen in dbContext.GenreMovies
select MovieGen.RowID)
.Union
(from MusicGen in dbContext.GenreMusics
select MusicGen.RowID).Union(from PodcastGen in dbContext.GenrePodcasts select PodcastGen.RowID).ToList();
GridSortSearch.DataTextField = "MovieGenre";
GridSortSearch.DataSource = infoQuery;
GridSortSearch.DataBind();
I have two issues the query is only being populated with "RowID"
and the combobox/dropdown is failing at the "DataTextField"
Like I said you need to return the same rows on results to achieve what you want.
Something like this, notice the change to the selects and the name of DataTextField value.
var infoQuery =
(from MovieGen in dbContext.GenreMovies
select new { MovieGen.RowID, Genre=MovieGen.MovieGenre})
.Union
(from MusicGen in dbContext.GenreMusics
select new {MusicGen.RowID, Genre=MusicGen.MusicGenre).Union(from PodcastGen in dbContext.GenrePodcasts select new {PodcastGen.RowID, Genre=PodcastGen.PodcastGenre).ToList();
GridSortSearch.DataTextField = "Genre";
GridSortSearch.DataSource = infoQuery;
GridSortSearch.DataBind();
I couldn't compile/test this where I am at the moment but should work.

LINQ Group By selecting with many-to-many association table

I have two models, Plans and Bookmarks, which are associated in a many-to-many relationship with an association table in the database. Specifically I'm looking at the situation where a Bookmark is associated with multiple Plans, like below...
BookmarkID | PlanID
A | 1
A | 2
B | 2
I'd want to select all BookmarkIDs where there is no association with a particular PlanID. So if PlanID = 1, I'd want to select B but not A.
For bonus points, I can easily take the BookmarkID result and get all the Bookmarks with a second linq query, but it would be cool to do this inline with a select function or soemthing.
I believe you want to use All like this:
int planId = 1;
var query = from b in context.Bookmarks
where b.Plans.All(p => p.PlanID != planId)
select b.BookmarkID;

How to get Name-property from 'Class' by ClassId from 'Table1' using LinQ?

I have 2 table in db. First table its all description, second table description one partial in the first table.Its look like:
+----------+ +----------+
I Table1 I I Class I
+----------+ +----------+
I Id I I Id I
I ClassId I <- I Name I
+----------+ +----------+
Main table its table1.Connection tables are available.
[HttpPost]
public ActionResult RoomFound(int className, FormCollection collection)
{
var example = db.table1.Where(p => p.ClassId == className);
ViewBag.Ex = example.ToList();
}
And now, when i create View and show the result, it shows me ClassId like numbers, but i want to see string format from table2. How can i connect ties from table2 (Class) in my main table (table1).
Assuming className is in fact a ClassId then you have no need to even query the Table1 table, just query the Class table directly i.e.
ViewBag.Ex = db.Class.Where(p => p.Id == className).Select(p => p.Name).ToList();
However, I will point out there is a clear relationship here between Table1 and Class therefore it's generally a good idea to define this at DB level and have this carried through to your ORM model which automatically gives you navigation properties e.g.
var t = db.table1.Where(p => p.ClassId == className);
ViewBag.Ex = t.Select(p => p.Class.Name).ToList();
Like I said though, it doesn't look like you even need to query the Table1 table at all here.

How to set an FK column value without retrieve it

i want to set a new value to my entity objects FK column, but i cant find the property to set. I dont want to get record from db.
I have a db like that
Db Tables:
Concept ConceptType
-Id (PK) -Id(PK)
-Name -Name
-ConceptTypeId(FK) (ALLOW NULL)
Code:
Concept conceptToUpdate = new Concept() { Id = 1 };
ConceptType conceptType = new ConceptType() { Id = 5 };
db.AttachTo("Concept", conceptToUpdate);
db.AttachTo("ConceptType", conceptType);
conceptToUpdate.ConceptType = conceptType;
db.SaveChanges();
This code is working if ConceptTypeId(FK) column is NULL before. If it is not NULL it gives exception. I trace the sql query, the problem is on sql query because it is checking that old value is NULL :S
SQL QUERY: (from SQL Profiler)
exec sp_executesql N'update [dbo].[Concept]
set [ConceptTypeId] = #0
where (([Id] = #1) and [ConceptTypeId] is null)
',N'#0 int,#1 int',#0=5,#1=1
The reason it fails is that in 3.5 SP1 is that for relationships the old FK value is part of the concurrency check, as you found via SQL profiler.
What you need is something like this:
Concept conceptToUpdate = new Concept() {
Id = 1 ,
ConceptType = new ConceptType {Id = OriginalFKValue}
};
ConceptType conceptType = new ConceptType() { Id = 5 };
db.AttachTo("Concept", conceptToUpdate);
db.AttachTo("ConceptType", conceptType);
conceptToUpdate.ConceptType = conceptType;
db.SaveChanges();
This means you need to know not just the Id of the thing you want to update, but also it's original FK values, which is of course a real pain.
Hence a new feature in EF 4.0 called FK Associations. With FK Associations the original value of the FK is not part of the concurrency check.
Hope this helps
Alex

Categories

Resources