I have the following suggestions:
1:
I would add something like a IsTransient
property to the entities. It returns true
if the PK is 0, otherwise it returns false
.
You could use this property to change your method as follows:
IsTransient
== true? -> InsertIsTransient
== false? -> Your existing code with the database check
Make that property virtual and you will even be able to support entities with "strange" PK by overriding IsTransient
.
2:
If you don't like adding this to your entities, you still could create an extension method that encapsulates this logic. Or even add that check directly into your InsertOrUpdate
.
As you don't have a common base class for your entities those suggestions will become a bit tedious. You basically would have to have one extension method per entity.
3:
If you have a convention in place for the PK, you could use dynamic
to access the ID property:
dynamic dynamicEntity = entity;
if(dynamicEntity.Id == 0)
{
// Insert
}
else
{
// Current code.
}
4:
Seeing that adding a transient entity to the context breaks things for all following transient items, it might be a good idea to add the transient items to a list instead of the context.
Only add them to the context when it is going to be committed. I am sure there is a hook for this, which you can use:
List<object> _newEntities;
private override OnCommit()
{
foreach(var newEntity in newEntities)
DatabaseContext.Entry(newEntity).State = EntityState.Added;
}
public virtual T InsertOrUpdate<T>(T entity) where T : class
{
var databaseEntity = this.GetEntityByPrimaryKey(entity);
if (databaseEntity == null)
_newEntities.Add(entity);
else
this.DatabaseContext.Entry(databaseEntity).CurrentValues.SetValues(entity);
return databaseEntity;
}