C#, Linq2SQL: Создание предиката для нахождения элементов во многих диапазонах

ElementTree ожидает объект Element в качестве аргумента, а не имя файла с исходным кодом XML. Вам необходимо проанализировать файл с помощью функции parse() API ElementTree.

Вам нужен полный путь + имя файла для записи файла результатов и фактически используйте os.path.join() для объединения пути и имени файла.

#!/usr/bin/env python3
import os
import xml.etree.ElementTree as ET


def main():
    path_names = [
        '/home/user/temp/a',
        '/home/user/temp/b',
        '/home/user/temp/c',
        '/home/user/temp/d',
        '/home/user/temp/e',
    ]
    for path in path_names:
        filename = os.path.join(path, 'config.xml')
        tree = ET.parse(filename)
        for element in tree.iter('url'):
            print(element.text)
            element.text = 'new value'
        tree.write(filename)


if __name__ == '__main__':
    main()
8
задан Svish 20 February 2009 в 13:20
поделиться

2 ответа

Использование с дженериками проблематично, так как C# не поддерживает операторы на дженериках - значение, что необходимо было бы записать выражение вручную. И поскольку мы уже видели, представьте работы в виде строки по-другому. Но для остальных, как насчет чего-то как (непротестированный):

(отредактированный для нескольких диапазонов)

    public static IQueryable<TSource> WhereBetween<TSource, TValue>(
        this IQueryable<TSource> source,
        Expression<Func<TSource, TValue>> selector,
        params Range<TValue>[] ranges)
    {
        return WhereBetween<TSource,TValue>(source, selector,
            (IEnumerable<Range<TValue>>) ranges);
    }

    public static IQueryable<TSource> WhereBetween<TSource, TValue>(
        this IQueryable<TSource> source,
        Expression<Func<TSource, TValue>> selector,
        IEnumerable<Range<TValue>> ranges)
    {
        var param = Expression.Parameter(typeof(TSource), "x");
        var member = Expression.Invoke(selector, param);
        Expression body = null;
        foreach(var range in ranges)
        {
            var filter = Expression.AndAlso(
                Expression.GreaterThanOrEqual(member,
                     Expression.Constant(range.A, typeof(TValue))),
                Expression.LessThanOrEqual(member,
                     Expression.Constant(range.B, typeof(TValue))));
            body = body == null ? filter : Expression.OrElse(body, filter);
        }            
        return body == null ? source : source.Where(
            Expression.Lambda<Func<TSource, bool>>(body, param));
    }

Примечание; использование Выражения. Вызовите средства, они будут, вероятно, работать над LINQ-SQL, но не EF (в данный момент; надо надеяться, зафиксированный в 4,0).

С использованием (протестированный на Northwind):

Range<decimal?> range1 = new Range<decimal?>(0,10),
                range2 = new Range<decimal?>(15,20);
var qry = ctx.Orders.WhereBetween(order => order.Freight, range1, range2);

Генерация TSQL (переформатировала):

SELECT -- (SNIP)
FROM [dbo].[Orders] AS [t0]
WHERE (([t0].[Freight] >= @p0) AND ([t0].[Freight] <= @p1))
OR (([t0].[Freight] >= @p2) AND ([t0].[Freight] <= @p3))

Что мы хотели;-p

7
ответ дан 5 December 2019 в 21:23
поделиться

Вы получаете ту ошибку, потому что все для LINQ к SQL должно быть в форме Выражения. Попробуйте это

public static Expression<Func<T,bool>> ToPredicate<T>(
    this IEnumerable<Range<int>> range, 
    Expression<Func<T, int>> selector
) {
    Expression<Func<T, bool>> p = PredicateBuilder.False<T>();
    Func<T, int> selectorFunc = selector.Compile();
    foreach (Range<int> r in range)
    {
        int a = r.A;
        int b = r.B;
        p = p.Or(ø => selectorFunc(ø) >= a && selectorFunc(ø) <= b);
    }
    return p;
}

Заметьте, что я компилирую селектор перед использованием его. Это должно работать с помехой, я использовал что-то как она в прошлом.

0
ответ дан 5 December 2019 в 21:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: