I like the fact that AddOrUpdate let's you specify a filter to check to avoid adding duplicates. But I would like similar functionality without the update.
Right now I do something like this:
var checkProfile = from p in db.Profile
where p => p.LastName == newProfile.lastName
&& p => p.FirstName == newProfile.firstName
&& p => p.Middle== newProfile.middle
select p;
if (checkProfile.FirstOrDefault() == null)
{
db.Profile.Add(newProfile);
db.SaveChanges();
}
I know I can do something like this:
db.Profile.AddOrUpdate(p => new {p.LastName, p.FirstName, p.Middle}, newProfile);
db.SaveChanges();
But I would rather skip modifying the data in this case.
The first example does what I want but with more code. Is there a simpler/cleaner way to do what I want in the first example?
Update:
I like Ognyan Dimitrov's suggestion. I'm trying to implement it. My models inherit from BaseEntity. Can I put a generic version of that there?
My model is defined:
public class Address :BaseEntity
{
My BaseEntity:
public class BaseEntity
{
public virtual T AddIfNotExists<T>(T entity, Expression<Func<T, bool>> predicate = null)
{
var exists = predicate != null ? DbSet.Any(predicate) : DbSet.Any();
return !exists ? DbSet.Add(entity) : null;
}
}
I'm getting errors for Any(...) and Add(...). The error for Add(...) is 'An object reference is required for the non-static field, method, or property 'System.Data.Entity.DbSet.Add(object)' '
Should I be using this.Add(object) ?
Update 2:
I've created this code:
public static class DbSetExtensions
{
public static T AddIfNotExists<T>(this DbSet<T> dbSet, T entity, Expression<Func<T, bool>> predicate = null) where T : class, new()
{
var exists = predicate != null ? dbSet.Any(predicate) : dbSet.Any();
return !exists ? dbSet.Add(entity) : null;
}
}
Now I'm trying to call it like this, but it's not correct. Forgive my lack of understanding.
_db.ProfileIdentifier.AddIfNotExists(newIdentifier,
pi => new {pi.ProfileId, pi.ProfileIdentifierTypeId, pi.ProfileIdentifierValue});
Update - Solution:
I can call the DbSetextensions like this:
_db.ProfileIdentifier.AddIfNotExists(newIdentifier,
pi => pi.ProfileId == profileId &&
pi.ProfileIdentifierTypeId == (int)type &&
pi.ProfileIdentifierValue == value);
Thanks a lot for working with me Ognyan!!!
Have you tried to check if the entity exists and if not - add it? Like this :
UPDATE
using System.Linq.Expressions;
public class ContextWithExtensionExample
{
public void DoSomeContextWork(DbContext context)
{
var uni = new Unicorn();
context.Set<Unicorn>().AddIfNotExists(uni , x => x.Name == "James");
}
}
public static class DbSetExtensions
{
public static T AddIfNotExists<T>(this DbSet<T> dbSet, T entity, Expression<Func<T, bool>> predicate = null) where T : class, new()
{
var exists = predicate != null ? dbSet.Any(predicate) : dbSet.Any();
return !exists ? dbSet.Add(entity) : null;
}
}
You can use this method directly and remember to call DbContext.SaveChanges() after the call.
All the other answers are incorrect.
"Read before write" can violate data integrity without being put inside a transaction control.
In SQL Server, you can use merge statement. However merge statement is not available in EF.
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