2017-02-02 3 views
1

Когда я называю DbSet.FirstOrDefault() пропусканием предикат, который сравнивает общий тип TId, я получаю следующее исключение:Как запросить EntityFramework, используя общий тип свойства?

не удалось создать постоянное значение типа 'System.Object. только В этом контексте поддерживаются примитивные типы или типы перечислений.

Интерфейс типа выполняется запрос:

interface IEntity<TId> 
{ 
    TId id { get; set; } 
} 

Исключение брошено здесь:

public virtual TEntity Get<TEntity, TId>(TId id) where TEntity : class, IEntity<TId> 
{ 
    return dbContext.Set<TEntity>().FirstOrDefault(e => e.Id.Equals(id)); 
} 

функция будет работать только тогда, когда TId ограничен в struct. Как включить string в качестве поддерживаемого типа? Если это невозможно, можно ли выполнить задачу по-другому?

ответ

1

Это будет работать для строк тоже:

public virtual TEntity Get<TEntity, TId>(TId id) 
    where TEntity : class, IEntity<TId> 
    where TId: IEquatable<TId> 
{ 
    return dbContext.Set<TEntity>().FirstOrDefault(e => e.Id.Equals(id)); 
} 
+0

Как я могу продлить его на работу для массивов этих примитивов тоже? Пример: int [] и строка []. Благодарю. – user845279

+0

Я не думаю, что вы можете. Равенство для множеств (RDBMSs не имеет понятия массивов) слишком велико, и в SQL нет прямой поддержки '==' -like. Рассмотрим, например, '[1,2]' и '[2,1]'. Они равны вам? Является ли заказ важным? Что относительно '[null, 1]' и '[null, 1]'? Вы беспокоитесь о тройной логике здесь или нет и т. Д. – UserControl

+0

Я работаю с MS Sql, который имеет тип Binary []. Он преобразуется в System.Byte []. – user845279

1

Вы можете просто использовать Find метод:

public virtual TEntity Get<TEntity, TId>(TId id) where TEntity : class, IEntity<TId> 
{ 
    return dbContext.Set<TEntity>().Find(id); 
} 
+0

Я пробовал это, и он работает, но он не подходит для случаев, когда первичный ключ является составным. – user845279

+0

Странно, как вы это пробовали? 'dbContext.Set () .Find (id1, id2);'? –

+0

Как вы упомянули в своем посте. Просто, используя 'Find()', вы не можете использовать только один из ключей. – user845279