2015-10-30 4 views
3

У меня есть эта родовая версия findById() метода (KeyType и EntityType являются шаблонными параметрами на уровне класса):Generic findById с Entity Framework и составные ключи

public EntityType findById(KeyType key) 
{ 
    log.LogDebugStart(); 
    log.LogDebug("id=" + key); 

    EntityType data; 

    using (ObjectContextWrapper contextWrapper = TransactionHelper.GetContextWrapper()) 
    { 
     Entities bdd = contextWrapper.GetContext(); 

     DbSet<EntityType> set = bdd.Set<EntityType>(); 

     data = set.Find(key); 
    } 

    log.LogDebugEnd(); 
    return data; 
} 

Это хорошо работает с ключами одноколоночных (экс : KeyType = long), но я не могу заставить его работать с составным первичным ключом (Ex: KeyType: long []).

Исключение я получаю:

Число первичных ключевых значений, передаваемых должны соответствовать число первичных ключевых значений, определенных на сущности. Название параметра: keyValues ​​

Сущности генерируются из базы данных с помощью файла .edmx. Оба столбца в моем случае настроены на первичный ключ. В отладчике я очень хорошо вижу, что ключ имеет тип short [2].

Я думал, что это может быть связано с тем, что мой метод не принимает аргумент «params» и что каким-то образом весь массив будет передан как один параметр в метод Find(), но это должно быть хорошо, как пока я передаю массив моему методу findById() ...

ответ

4

Вам нужно преобразовать значения ключей в массив объектов, то есть object[].

Я предлагаю вам заменить это:

data = set.Find(key); 

с этим:

if(key is Array) 
{ 
    data = set.Find((key as IEnumerable).Cast<object>().ToArray()); 
} 
else 
{ 
    data = set.Find(key); 
} 
+0

СПАСИБО! Я знал, что это что-то в этом роде, но я не мог понять, как правильно настроить свой параметр ... – Kaidjin

1

Почему бы не использовать params? paramsobject решит эту проблему.

public EntityType findById(params object[] keys) 
{ 
    log.LogDebugStart(); 
    log.LogDebug("id=" + keys.Aggregate((a, b) => a.ToString() + ", " + b.ToString())); 

    EntityType data; 

    using (ObjectContextWrapper contextWrapper = TransactionHelper.GetContextWrapper()) 
    { 
     Entities bdd = contextWrapper.GetContext(); 

     DbSet<EntityType> set = bdd.Set<EntityType>(); 

     data = set.Find(keys); 
    } 

    log.LogDebugEnd(); 
    return data; 
} 

Следует помнить, что Find метод принимает только массив object. Посмотрите https://msdn.microsoft.com/en-us/library/gg696418(v=vs.113).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1

+0

Тот факт, что мой параметр был массив коротких, вероятно, проблема, спасибо. Я закончил использовать решение Якуба, но вы помогли мне понять, что случилось. Благодарю. – Kaidjin