Динамическая помощь Linq, разные ошибки в зависимости от объекта, переданного в качестве параметра? - PullRequest
5 голосов
/ 09 апреля 2010

У меня есть entityDao, который наследуется каждым из моих objectDaos. Я использую Dynamic Linq и пытаюсь заставить работать несколько общих запросов.

В моем универсальном методе в EntityDao есть следующий код:

public abstract class EntityDao<ImplementationType> where ImplementationType : Entity
{ 
    public ImplementationType getOneByValueOfProperty(string getProperty, object getValue){
    ImplementationType entity = null;
    if (getProperty != null && getValue != null) 
    {
        LCFDataContext lcfdatacontext = new LCFDataContext(); 
         //Generic LINQ Query Here
         entity = lcfdatacontext.GetTable<ImplementationType>().Where(getProperty + " =@0", getValue).FirstOrDefault();
         //.Where(getProperty & "==" & CStr(getValue))
     }

 //lcfdatacontext.SubmitChanges()
 //lcfdatacontext.Dispose()

return entity;
}

Затем я выполняю следующий вызов метода в модульном тесте (все мои objectDaos наследуют entityDao):

[Test]
public void getOneByValueOfProperty()
{
    Accomplishment result = accomplishmentDao.getOneByValueOfProperty
        ("AccomplishmentType.Name", "Publication");

    Assert.IsNotNull(result);
}

Вышеуказанные проходы (AccomplishmentType имеет отношение к выполнению)

Accomplishment result = accomplishmentDao.getOneByValueOfProperty("Description", "Can you hear me now?");
Accomplishment result = accomplishmentDao.getOneByValueOfProperty("LocalId", 4);

Обе вышеперечисленные работы. Тем не менее,

 Accomplishment result = accomplishmentDao.getOneByValueOfProperty
    ("Id", New Guid("95457751-97d9-44b5-8f80-59fc2d170a4c"));

Не работает и говорит следующее:

Operator '=' incompatible with operand types 'Guid' and 'Guid

Почему это происходит? Guid нельзя сравнивать? Я тоже пробовал ==, но та же ошибка. Что еще более запутанно, так это то, что каждый пример Dynamic Linq, который я видел, просто использует строки, будь то использование параметризованного предиката where или этот, который я прокомментировал:

//.Where(getProperty & "==" & CStr(getValue))

С Cstr или без него многие типы данных не работают с этим форматом. Я попытался установить getValue для строки, а не для объекта, но потом я просто получаю другие ошибки (например, строка из нескольких слов остановит сравнение после первого слова).

Чего мне не хватает, чтобы заставить это работать с GUID и / или любым типом данных? В идеале я хотел бы иметь возможность просто передать строку для getValue (как я видел для каждого другого динамического примера LINQ) вместо объекта и заставить его работать независимо от типа данных столбца.

Ответы [ 2 ]

6 голосов
/ 09 апреля 2010

Welp Я понял это, Dynamic LINQ изначально не поддерживает Сравнение GUID (так глупо!). Я нашел этот маленький кусочек: https://connect.microsoft.com/VisualStudio/feedback/details/333262/system-linq-dynamic-throws-an-error-when-using-guid-equality-in-where-clause

Вы просто зашли в файл Dynamics.cs, заменив интерфейс IEqualitySignatures следующим:

interface IEqualitySignatures : IRelationalSignatures
{
    void F(bool x, bool y);
    void F(bool? x, bool? y);
    void F(Guid x, Guid y);
    void F(Guid? x, Guid? y);
}

Теперь мой getOneByValueOfProperty работает постоянно!

0 голосов
/ 18 декабря 2012

для Guid это должно работать:

.Where(getProperty + ".Equals(@0)", getValue);

(обратите внимание, что параметр getValue должен иметь тип Guid )

...