Reputation: 11796
I'm working on a reusable database repository method for attaching and saving entities to a database using EntityFramework 4.3.
private void SaveObject<T>(T entityToSave, DbSet<T> dbSet) where T : class
{
if (db.Entry(entityToSave).State == EntityState.Detached)
{
if (entityToSave.Id == Guid.Empty) // how do I access the Id property?
dbSet.Add(entityToSave);
else
db.Entry(entityToSave).State = EntityState.Modified;
}
}
The problem that I'm running into is that I need to tell my method which property is the Id so I can check to see if it is set or not. If it is empty, then I know I am creating a brand new record. Otherwise I am modifying an existing record.
How do I tell my method what the Id property is?
Upvotes: 2
Views: 163
Reputation: 112279
As others have shown, you can solve the problem by using an interface. Another possibility is to define an accessor delegate
private void SaveObject<T>(T entityToSave, DbSet<T> dbSet, Func<T,Guid> accessId)
{
...
Guid id = accessId(entityToSave);
...
}
call with
SaveObject(entityToSave, dbSet, e => e.Id)
SaveObject(otherEntityToSave, dbSet, e => e.UserID)
The advantage over an interface, is that the ids can have different names and, together with a second generic parameter, even different types
private void SaveObject<T,I>(T entityToSave, DbSet<T> dbSet, Func<T,I> accessId)
{
...
I id = accessId(entityToSave);
...
}
Upvotes: 1
Reputation: 42497
You need an interface or base class that defines the Id
property, and use that as your generic constraint. Example:
public interface IEntity
{
Guid Id { get; }
}
private void SaveObject<T>(T entityToSave, DbSet<T> dbSet) where T : class, IEntity
{
if (db.Entry(entityToSave).State == EntityState.Detached)
{
if (entityToSave.Id == Guid.Empty) // how do I access the Id property?
dbSet.Add(entityToSave);
else
db.Entry(entityToSave).State = EntityState.Modified;
}
}
Upvotes: 3
Reputation: 887285
You need to create an interface containing the Id
property.
Make all of your entity classes implement this interface and constrain T
to implement it. (where T : IHasId
)
You will then be able to access all of the members of this interface in your method.
Upvotes: 3