2015-01-21 2 views
1

Я использую транзакцию на Redis & с использованием поставщика StackExchange.Redis.'StackExchange.Redis.ITransaction' не содержит определения для 'StringSetAsync'

У меня есть большая партия операций StringSetAsync для транзакции.

И я получил сообщение об ошибке при использовании StringSetAsync:

RuntimeBinderException был пойман

'StackExchange.Redis.ITransaction' не содержит определения для '' StringSetAsync

StackTrace:

at CallSite.Target (Closure, CallSite, ITransaction, String, Object) в Repository.RedisDatabaseContextBase.SetRecord (IBasicRedisEntity redisEntity, Boolean isNewRecord)

====

Добавлено:

Вот пример кода, который отражает проблему. Марк был прав, это все о динамический.

try 
{ 
    ConnectionMultiplexer cm = ConnectionMultiplexer.Connect("localhost:6380,allowAdmin=true"); 
    var db = cm.GetDatabase(); 

    ITransaction transaction = db.CreateTransaction(); 

    dynamic pp = new byte[5] {1, 2, 3, 4, 5}; 

    transaction.StringSetAsync("test", pp); 

    if (transaction.Execute()) 
    { 
    Console.Write("Committed"); 
    } 
    else 
    { 
    Console.Write("UnCommitted"); 
    } 

    Console.ReadLine(); 
} 
catch (Exception e) 
{ 
    Console.WriteLine(e); 
} 
+0

RuntimeBinderException предполагает, что вы используете 'dynamic' - это правильно? –

+0

Нет, я использую дженерики. Но в конце это все равно просто: transaction.StringSetAsync (ключ, значение); // error –

+0

Ненавижу говорить об этом, но упоминание «CallSite» выглядит следующим образом: ** настоятельно предлагает ** 'dynamic' в игре здесь - в этом случае да: он будет терпеть неудачу для нескольких сценариев (явная реализация, например). У вас есть пример кода, где это происходит? Включая типы любых переменных (т. Е. Если у вас есть 'obj.StringSetAsync (...)', что такое 'obj'?) –

ответ

0

В некотором смысле это правильно: нет перегрузки, которая принимает byte[]. Есть один, который принимает RedisValue, но что не то же самое. dynamic решение метода может быть глючным - как для явных реализаций интерфейса, так и для операторов преобразования: оба применяются здесь!

Я хотел бы предложить:

object pp = new byte[5] {1, 2, 3, 4, 5}; 

if(pp is byte[]) 
    transaction.StringSetAsync("test", (byte[])pp); 
else if (pp is string) 
    transaction.StringSetAsync("test", (string)pp); 
else if (pp is RedisValue) 
    transaction.StringSetAsync("test", (RedisValue)pp); 
else 
    throw new NotSupportedException(
     "Value is not usable: " + pp.GetType().FullName); 

Альтернативой может быть:

dynamic pp = new byte[5] {1, 2, 3, 4, 5}; 
transaction.StringSetAsync("test", (RedisValue)pp); 

Это должно работать в теории, но все еще немного ненужным ИМО.

+0

Эта работа на практике тоже, и я согласен с вами: лучше проверить кастинг, чтобы предотвратить ошибки. –