Для коллекции "records" состоящей из экземпляров класса FileCabinetRecord
`public class FileCabinetRecord
{
public short Status { get; set; } = 0;
public int Id { get; set; }
public char Sex { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public decimal Salary { get; set; }
public DateTime DateOfBirth { get; set; }
}`
я пытаюсь создать команду where, наподобие одноименной команды из sql, но при компиляции делегата из дерева выражений программа падает с исключением:
"InvalidOperationException: На переменную "record" типа "FileCabinetRecord" имеется ссылка из области "", но она не определена"
В команде предусмотрено использование только сравнений на эквивалентность, никаких иных наподобие > < != .
Просмотрел кучу примеров, но понять не могу - где я ошибаюсь...
Исключение выбрасывается при попытке скомпилировать whereExpr в whereDelegate.
Вот мой код.
Это моё первое знакомство с рефлексией и деревьями выражений. Пожалуйста, покажите где я ошибся и подскажите как поправить код в целом.
Строка с выражениями следующая: "select firstname, salary, sex where firstname = 'qwer1' or firstname = 'qwer2' and id = '1' or id = '2'".
В метод Where я отдавал только часть строки, стоящую после "where".
P.S. с регулярными выражениями я "на вы".
public static IEnumerable<FileCabinetRecord> Where(string expressions, IEnumerable<FileCabinetRecord> records)
{
Regex regex = new Regex(@"([a-z]{2,}\s*=\s*\p{P}+[\w|\/]*\p{P}+)*([a-z]{2,})*", RegexOptions.IgnoreCase);
var matches = regex.Split(expressions).Select(r => r).Where(r => !string.IsNullOrEmpty(r) & !string.IsNullOrWhiteSpace(r)).ToList();
BinaryExpression left, right, resulted = default(BinaryExpression);
var record = Expression.Parameter(typeof(FileCabinetRecord), "record");
int i = 0;
while (i < matches.Count)
{
if (i == 0)
{
left = EqualsExpressionFactory(matches[0]);
right = EqualsExpressionFactory(matches[2]);
resulted = matches[1].Equals("and", StringComparison.InvariantCultureIgnoreCase) ? MakeAndAlsoExpr(left, right) : MakeOrElseExpr(left, right);
i += 3;
}
else
{
left = resulted;
right = EqualsExpressionFactory(matches[i + 1]);
resulted = matches[i].Equals("and", StringComparison.InvariantCultureIgnoreCase) ? MakeAndAlsoExpr(left, right) : MakeOrElseExpr(left, right);
i += 2;
}
}
var whereExpr = Expression<Func<FileCabinetRecord, bool>>.Lambda<Func<FileCabinetRecord, bool>>(resulted, record);
var selectExpr = Expression<Func<FileCabinetRecord, FileCabinetRecord>>.Lambda<Func<FileCabinetRecord, FileCabinetRecord>>(record, record);
var whereDelegate = whereExpr.Compile(); // Тут выбрасывается исключение
var selectDelegate = selectExpr.Compile(); // До сюда даже не дошло ни разу
var res = records.Select(selectDelegate).Where(whereDelegate);
return res;
}
public static BinaryExpression MakeAndAlsoExpr(Expression left, Expression right)
{
return Expression.AndAlso(left, right);
}
public static BinaryExpression MakeOrElseExpr(Expression left, Expression right)
{
return Expression.OrElse(left, right);
}
public static BinaryExpression EqualsExpressionFactory(string expression)
{
var args = expression.Split(new char[] { '=' }, 2).Select(s => s.Trim(' ', '\'')).ToList();
var propName = args[0].ToUpperInvariant();
string value = args[1];
BinaryExpression be;
switch (propName)
{
case "ID":
be = MakeBinary(propName, int.Parse(value));
break;
case "SEX":
be = MakeBinary(propName, char.Parse(value));
break;
case "FIRSTNAME":
case "LASTNAME":
be = MakeBinary(propName, value);
break;
case "SALARY":
be = MakeBinary(propName, decimal.Parse(value));
break;
case "DATEOFBIRTH":
be = MakeBinary(propName, DateTime.Parse(value));
break;
default:
return null;
}
return be;
}
public static BinaryExpression MakeBinary<T>(string propName, T value)
{
MemberInfo property = properties[propName];
MemberExpression propertyExpr = Expression.MakeMemberAccess(Expression.Parameter(typeof(FileCabinetRecord), "record"), property);
BinaryExpression Equals = Expression.Equal(propertyExpr, Expression.Constant(value, propertyExpr.Type));
return Equals;
}
public static Type recordType = typeof(FileCabinetRecord);
public static Dictionary<string, MemberInfo> properties = new Dictionary<string, System.Reflection.MemberInfo>
{
{"ID", recordType.GetProperty("Id")},
{"SEX", recordType.GetProperty("Sex")},
{"FIRSTNAME", recordType.GetProperty("FirstName")},
{"LASTNAME", recordType.GetProperty("LastName")},
{"SALARY", recordType.GetProperty("Salary")},
{"DATEOFBIRTH", recordType.GetProperty("DateOfBirth")},
};
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Я делаю парсер, использую AnglesSharp и при попытке получить ресурсы сайта он кидает мне ошибку, мол слишком много запросов, хотя в этой тестовой...
Всем приветЧтение руководства и поиск в интернете не помогают мне, видимо потому что плохо формулирую вопрос
Проблема: После того, как я повесил функцию на хук save_post - сама функция и хук отрабатывается полностьюЗапись и ее изменения сохраняются