根据您提供的唯一必要代码:
where T : class
// and
_DbContext.Set<T>().FirstOrDefaultAsync(x => x.PersonalId == entityId);
//.OfType<T>() is not necessary
如果我们把它写得更明确,它将是:
_DbContext.Set<T>().FirstOrDefaultAsync((object x) => x.PersonalId == entityId);
因为class
的default是object
,而object没有名为PersonalId
的属性.
因此,您需要更新T
的约束,以包括具有该属性的接口或具有该属性的类:
// abstract not required, just recommended
public abstract class EntityBase
{
public int PersonalId { get; set; }
}
where T : EntityBase
// or
public interface class IEntityBase
{
int PersonalId { get; }
}
where T : IEntityBase, class
然后,您必须确保您想要使用的任何T都必须派生自您 Select 的T:
public class Person : EntityBase
{
// ...
}
public class Person : IEntityBase
{
// ...
}
所以我们最终会有
public class BaseRepository<T> : IBaseRepository<T> where T : IEntityBase, class
{
// ...
public virtual async Task<T> GetByPersonalId(int entityId)
{
return await _DbContext
.Set<T>()
.FirstOrDefaultAsync(x => x.PersonalId == entityId);
}
}
哪里
(x => x.PersonalId == entityId)
// would written more explicitly would be
((IEntityBase x) => x.PersonalId = entityId)
使用派生类型时:
public class PersonRepository : BaseRepository<Person>
where T : IEntityBase, class
{
}
谓词(x => bool
)只能使用IEntityBase
的属性,Set<T>()
返回的DBSet将是实例化存储库中的派生类型:
using (var personRepo = new PersonRepository(db))
{
Person person = personRepo.GetByPersonalId(1);
// or
var person = personRepo.GetByPersonalId(1);
}