В зависимости от того, что вы на самом деле хотите сделать, я рассмотрел бы переименование свойств в классе в Id, а затем сопоставил бы их с ключами в базе данных в конфигурации модели:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntityType>().Property(k => k.Id).HasColumnName("CustomerId");
// ...
}
Однако, если вы действительно хотите придерживаться этих свойств и все еще хотите использовать универсальные методы для их получения (бог знает почему), вам, вероятно, придется выставить функцию на некотором интерфейсе, который вы позже сможете использовать для сравнения ,
Возможно, что-то вроде этого:
// An interface that requires a func to match it's id
public interface IExpressionKeyEntity
{
// A func that takes an int and returns true if it's a match
// against the entity id
Func<int, bool> HasMatchingId { get; }
}
С самой простой реализацией:
// A simple customer class that implements the interface
public class Customer : IExpressionKeyEntity
{
// An id property that we don't know anything about from the outside
public int CustomerId { get; set; }
// A func that takes an id and returns true if it's a match against this entities id
public Func<int, bool> HasMatchingId => comparisonEntityId => comparisonEntityId == CustomerId;
}
А затем используйте его с некоторыми незначительными изменениями в методе GetById:
// GetById now requires an IExpressionKeyEntity to be retrieved
public async Task<TEntity> GetById<TEntity>(int id)
where TEntity : IExpressionKeyEntity
{
// Return the first match based on our func
return await _dbContext.Set<TEntity>()
.AsNoTracking()
.FirstOrDefault(q => q.HasMatchingId(id));
}
У меня такое чувство, что я сталкивался с некоторыми проблемами с Func и EF раньше, но технически это должно сработать. В противном случае вам придется копаться в выражениях.