Прочтите эту документацию, в которой объясняется, как linq и C # могут испытывать Отключить.
Поскольку ожидается, что выражения Linq будут сокращены до чего-то другого, кроме простых методов, вы можете обнаружить, что этот код ломается, если позже он используется в каком-либо контексте, отличном от Linq to Objects.
Это сказал
String.IsNullOrEmpty(fromname) ||
( !String.IsNullOrEmpty(fromname) &&
msg.FromName.ToLower().Contains(fromname.ToLower())
)
Плохо сформирован, так как он действительно должен быть
String.IsNullOrEmpty(fromname) ||
msg.FromName.ToLower().Contains(fromname.ToLower())
что делает приятным и ясным, что вы полагаетесь на то, что msg и msg.FromName оба также не равны нулю.
Чтобы упростить себе жизнь в C #, вы можете добавить следующий метод расширения строки
public static class ExtensionMethods
{
public static bool Contains(
this string self, string value, StringComparison comparison)
{
return self.IndexOf(value, comparison) >= 0;
}
public static bool ContainsOrNull(
this string self, string value, StringComparison comparison)
{
if (value == null)
return false;
return self.IndexOf(value, comparison) >= 0;
}
}
Затем используйте:
var messages = (from msg in dc.MessageItems
where msg.FromName.ContainsOrNull(
fromname, StringComparison.InvariantCultureIgnoreCase)
select msg);
Однако проблема не в этом. Проблема в том, что аспекты системы Linq to SQL пытаются использовать значение fromname
для построения запроса, который отправляется на сервер.
Поскольку fromname
является переменной, механизм перевода отключается и выполняет то, что от него требуется (создавая представление fromname
в нижнем регистре, даже если оно равно нулю, что вызывает исключение).
в этом случае вы можете либо сделать то, что вы уже обнаружили: оставить запрос как есть, но убедиться, что вы всегда можете создать ненулевое значение fromname с желаемым поведением, даже если оно равно нулю.
Возможно, лучше было бы:
IEnumerable<MessageItem> results;
if (string.IsNullOrEmpty(fromname))
{
results = from msg in dc.MessageItems
select msg;
}
else
{
results = from msg in dc.MessageItems
where msg.FromName.ToLower().Contains(fromname)
select msg;
}
Это не так уж важно, если запрос содержал другие ограничения и, таким образом, вызвал большее дублирование, но для простого запроса на самом деле должен приводить к более читаемому / поддерживаемому коду. Это неприятно, если вы полагаетесь на анонимные типы, но, надеюсь, это не проблема для вас.
person
ShuggyCoUk
schedule
21.04.2009