I want to add a Guid
identifier to a few of my entities.
My initial approach was to make it the Primary Key
for those entities. But that seems to make the rest of my code more complex.
For example we must now allow for multiple ID types in the generic repository and specify the PK type for each DbEntity
(code samples below).
Therefore I am considering maintaining a consistent int
PK on all entities, and adding the Guid
as an additional property when required. This also means that I don't have to worry about ensuring the Guid is not used as a clustering key.
Simpler code. No cluster worries. The 'additional property' approach looks like a winner to me.
However I don't see it mentioned, used or recommended anywhere. (In comparison there are plenty of articles disussing using a Guid for a PK).
Are there any disadvantages to this approach? Could doing things this way come back and bite me?
Using Only Int as PK
public class DbEntity
{
[Key]
public int ID { get; set; }
}
public class Car : DbEntity
{}
public class House: DbEntity
{}
public virtual T SelectByID(int id, params Expression<Func<T, object>>[] includeExpressions)
{
var set = includeExpressions.Aggregate<Expression<Func<T, object>>, IQueryable<T>>
(table, (current, expression) => current.Include(expression));
return set.SingleOrDefault(i => i.ID == id);
}
public virtual T SelectByGuid(string guid, params Expression<Func<T, object>>[] includeExpressions)
{
var set = includeExpressions.Aggregate<Expression<Func<T, object>>, IQueryable<T>>
(table, (current, expression) => current.Include(expression));
return set.SingleOrDefault(i => i.AdditionalGuidProperty == guid);
}
Using Both Int and Guid as PK
public class DbEntity<PKT>
{
[Key]
public PKT ID { get; set; }
}
public class Car : DbEntity<int>
{}
public class House : DbEntity<guid>
{}
public virtual T SelectByID(PKT id, params Expression<Func<T, object>>[] includeExpressions)
{
var set = includeExpressions.Aggregate<Expression<Func<T, object>>, IQueryable<T>>
(table, (current, expression) => current.Include(expression));
ParameterExpression parameter = Expression.Parameter(typeof(T), "s");
PropertyInfo propertyInfo = typeof(T).GetProperty("ID");
MemberExpression memberExpression = Expression.MakeMemberAccess(parameter, propertyInfo);
ConstantExpression constantExpression = Expression.Constant(id, typeof(PKT));
BinaryExpression binaryExpression = Expression.Equal(memberExpression, constantExpression);
Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(binaryExpression, parameter);
return set.SingleOrDefault(lambda);
}