Этот ответ, возможно, не поможет вам в зависимости от того, насколько «динамична» ситуация, когда вы вызываете этот метод, в основном, если вы знаете тип во время компиляции или нет. Если вы знаете это, вы можете написать общий метод:
public static class MyExtensions
{
public static int? GetId<TEntity>(this Context db, string name)
where TEntity : DomainEntity
{
return db.Set<TEntity>()
.Where(x => x.Name == name)
.Select(x => (int?)x.Id)
.FirstOrDefault();
}
}
Я изменил его на проекцию, потому что вам не нужно загружать полную сущность, если вам нужен только Id. Вы можете позволить базе данных выполнить выбор свойства, чтобы немного повысить производительность. Также я возвращаю nullable int в случае, если в базе данных нет совпадений с именем.
Вы можете назвать это в своем коде так:
int? id = db.GetId<WindowStyle>("abc");
Как видно из этого решения, вы должны указать тип WindowStyle
во время компиляции.
Это предполагает, что DomainEntity
не является частью вашей модели (нет DbSet<DomainEntity>
), а является просто базовым классом ваших сущностей. В противном случае решение Пола Кейстера было бы проще.
Редактировать
В качестве альтернативы вы также можете попробовать следующее:
public static class MyExtensions
{
public static int? GetId(this Context db, Type entityType, string name)
{
return ((IQueryable<DomainEntity>)db.Set(entityType))
.Where(x => x.Name == name)
.Select(x => (int?)x.Id)
.FirstOrDefault();
}
}
И назовите это:
int? id = db.GetId("abc", someType);
Будет сгенерировано исключение во время выполнения, если someType
не наследуется от DomainEntity
. Универсальная версия проверит это во время компиляции. Итак, если вы можете предпочесть первую версию.