I'm having a Entity-Set Countries, reflecting a database table '<'char(2),char(3),nvarchar(50> in my database.
Im having a parser that returns a Country[] array of parsed countries, and is having issues with getting it updated in the right way. What i want is: Take the array of countries, for those countries not already in the database insert them, and those existing update if any fields is different. How can this be done?
void Method(object sender, DocumentLoadedEvent e) { var data = e.ParsedData as Country[]; using(var db = new DataContractEntities) { //Code missing } }
I was thinking something like
for(var c in data.Except(db.Countries)) but it wount work as it compares on wronge fields.
Hope anyone have had this issues before, and have a solution for me. If i cant use the Country object and insert/update an array of them easy, i dont see much benefict of using the framework, as from performers i think its faster to write a custom sql script that inserts them instead of ect checking if an country is already in the database before inserting?
I added override equals to my country class:
public partial class Country { public override bool Equals(object obj) { if (obj is Country) { var country = obj as Country; return this.CountryTreeLetter.Equals(country.CountryTreeLetter); } return false; } public override int GetHashCode() { int hash = 13; hash = hash * 7 + (int)CountryTreeLetter[0]; hash = hash * 7 + (int)CountryTreeLetter[1]; hash = hash * 7 + (int)CountryTreeLetter[2]; return hash; } }
and then did:
var data = e.ParsedData as Country[]; using (var db = new entities()) { foreach (var item in data.Except(db.Countries)) { db.AddToCountries(item); } db.SaveChanges(); }
The most common data to cache in EF Core is transactional data. This is the frequently changing data that is created at runtime (e.g. customer, accounts, activities, etc.) and you cache it only for a short time during which your application reads it multiple times.
EF Core is an object-relational mapper (ORM). Object-relational mapping is a technique that enables developers to work with data in object-oriented way by performing the work required to map between objects defined in an application's programming language and data stored in relational datasources.
The Change Tracking tracks changes while adding new record(s) to the entity collection, modifying or removing existing entities. Then all the changes are kept by the DbContext level. These track changes are lost if they are not saved before the DbContext object is destroyed.
I would do it straightforward:
void Method(object sender, DocumentLoadedEvent e) { var data = e.ParsedData as Country[]; using(var db = new DataContractEntities) { foreach(var country in data) { var countryInDb = db.Countries .Where(c => c.Name == country.Name) // or whatever your key is .SingleOrDefault(); if (countryInDb != null) db.Countries.ApplyCurrentValues(country); else db.Countries.AddObject(country); } db.SaveChanges(); } }
I don't know how often your application must run this or how many countries your world has. But I have the feeling that this is nothing where you must think about sophisticated performance optimizations.
Edit
Alternative approach which would issue only one query:
void Method(object sender, DocumentLoadedEvent e) { var data = e.ParsedData as Country[]; using(var db = new DataContractEntities) { var names = data.Select(c => c.Name); var countriesInDb = db.Countries .Where(c => names.Contains(c.Name)) .ToList(); // single DB query foreach(var country in data) { var countryInDb = countriesInDb .SingleOrDefault(c => c.Name == country.Name); // runs in memory if (countryInDb != null) db.Countries.ApplyCurrentValues(country); else db.Countries.AddObject(country); } db.SaveChanges(); } }
The modern form, using later EF versions would be:
context.Entry(record).State = (AlreadyExists ? EntityState.Modified : EntityState.Added); context.SaveChanges();
AlreadyExists
can come from checking the key or by querying the database to see whether the item already exists there.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With