Использование IQueryable с Linq

Можно добавить дыры относительно легко сами. В основном треугольный к выпуклой оболочке точек ввода, согласно CGAL, и затем удаляют любой треугольник, центр вписанной окружности которого находится в любом из полигонов дыры (или вне любой из внешних границ). При контакте с большим количеством дыр в большом наборе данных методы маскирования могут использоваться для значительного ускорения этого процесса.

редактирование: общее расширение этой техники должно прополоть слабые треугольники на оболочке, где самый длинный край или самый маленький внутренний угол превышают данное значение. Это сформирует лучшую вогнутую оболочку.

244
задан SteveC 11 November 2013 в 21:49
поделиться

3 ответа

Ответ Марка Грейвелла очень полный, но я подумал, что добавлю кое-что и по этому поводу с точки зрения пользователя ...


Основное отличие от с точки зрения пользователя, когда вы используете IQueryable (с поставщиком, который поддерживает все правильно), вы можете сэкономить много ресурсов.

Например, если вы работаете против удаленная база данных, со многими системами ORM, у вас есть возможность получать данные из таблицы двумя способами: один возвращает IEnumerable , а другой возвращает IQueryable . Скажем, например, у вас есть таблица «Товары», и вы хотите получить все продукты, стоимость которых превышает 25 долларов.

Если вы это сделаете:

 IEnumerable<Product> products = myORM.GetProducts();
 var productsOver25 = products.Where(p => p.Cost >= 25.00);

Здесь происходит то, что база данных загружает все продукты, и передает их по сети в вашу программу. Затем ваша программа фильтрует данные. По сути, база данных выполняет SELECT * FROM Products и возвращает вам КАЖДЫЙ продукт.

С другой стороны, с правильным поставщиком IQueryable вы можете do:

 IQueryable<Product> products = myORM.GetQueryableProducts();
 var productsOver25 = products.Where(p => p.Cost >= 25.00);

Код выглядит так же, но разница здесь в том, что выполняемый SQL будет SELECT * FROM Products WHERE Cost> = 25 .

С точки зрения разработчика, это выглядит такой же. Однако с точки зрения производительности вы можете вернуть только 2 записи по сети вместо 20 000 ....

провайдер, с другой стороны, вы можете:

 IQueryable<Product> products = myORM.GetQueryableProducts();
 var productsOver25 = products.Where(p => p.Cost >= 25.00);

Код выглядит так же, но разница здесь в том, что выполняемый SQL будет SELECT * FROM Products WHERE Cost> = 25 .

С точки зрения разработчика, это выглядит так же. Однако с точки зрения производительности вы можете вернуть только 2 записи по сети вместо 20 000 ....

провайдер, с другой стороны, вы можете сделать:

 IQueryable<Product> products = myORM.GetQueryableProducts();
 var productsOver25 = products.Where(p => p.Cost >= 25.00);

Код выглядит так же, но разница в том, что выполняемый SQL будет SELECT * FROM Products WHERE Cost> = 25 .

С точки зрения разработчика, это выглядит одинаково. Однако с точки зрения производительности вы можете вернуть только 2 записи по сети вместо 20 000 ....

482
ответ дан 23 November 2019 в 03:07
поделиться

Если вы хотите увидеть только , что используется : SD C # Test Coverage Tool

Если вы хотите увидеть , как часто он используется: Только разработчик LINQ должен знать кровавые подробности.


Re комментарии; Я не совсем уверен, что вы хотите в качестве примера, но рассмотрите LINQ-to-SQL; центральным объектом здесь является DataContext , который представляет нашу оболочку базы данных. Обычно это свойство для каждой таблицы (например, Клиенты ), а таблица реализует IQueryable . Но мы не используем это напрямую; подумайте:

using(var ctx = new MyDataContext()) {
    var qry = from cust in ctx.Customers
              where cust.Region == "North"
              select new { cust.Id, cust.Name };
    foreach(var row in qry) {
        Console.WriteLine("{0}: {1}", row.Id, row.Name);
    }
}

это становится (компилятором C #):

var qry = ctx.Customers.Where(cust => cust.Region == "North")
                .Select(cust => new { cust.Id, cust.Name });

, которое снова интерпретируется (компилятором C #) как:

var qry = Queryable.Select(
              Queryable.Where(
                  ctx.Customers,
                  cust => cust.Region == "North"),
              cust => new { cust.Id, cust.Name });

Важно отметить, что статические методы в Queryable принимают деревья выражений, которые - вместо обычного IL скомпилироваться в объектную модель. Например, просто глядя на «Где», мы получаем нечто сопоставимое с:

var cust = Expression.Parameter(typeof(Customer), "cust");
var lambda = Expression.Lambda<Func<Customer,bool>>(
                  Expression.Equal(
                      Expression.Property(cust, "Region"),
                      Expression.Constant("North")
                  ), cust);

... Queryable.Where(ctx.Customers, lambda) ...

Didn ' Компилятор много для нас делает? Эту объектную модель можно разобрать, проверить, что она означает, и снова собрать вместе с помощью генератора TSQL - что-то вроде:

 SELECT c.Id, c.Name
 FROM [dbo].[Customer] c
 WHERE c.Region = 'North'

(строка может оказаться параметром; я не помню)

Ничего из этого было бы невозможно, если бы мы просто использовали делегата. И этот является точкой Queryable / IQueryable : он предоставляет точку входа для использования деревьев выражений.

Все это очень сложно , поэтому хорошо, что компилятор делает ее приятной и легкой для нас.

Для получения дополнительной информации см. « C # in Depth » или « LINQ в действии » , оба из которых охватывают эти темы.

и снова собрать вместе с помощью генератора TSQL - что-то вроде:

 SELECT c.Id, c.Name
 FROM [dbo].[Customer] c
 WHERE c.Region = 'North'

(строка может оказаться параметром; я не помню)

Ничего из этого было бы невозможно, если бы мы просто использовали делегат. И этот является точкой Queryable / IQueryable : он предоставляет точку входа для использования деревьев выражений.

Все это очень сложно , поэтому хорошо, что компилятор делает ее приятной и легкой для нас.

Для получения дополнительной информации см. « C # in Depth » или « LINQ в действии » , оба из которых охватывают эти темы.

и снова собрать вместе с помощью генератора TSQL - что-то вроде:

 SELECT c.Id, c.Name
 FROM [dbo].[Customer] c
 WHERE c.Region = 'North'

(строка может оказаться параметром; я не помню)

Ничего из этого было бы невозможно, если бы мы просто использовали делегат. И этот является точкой Queryable / IQueryable : он предоставляет точку входа для использования деревьев выражений.

Все это очень сложно , поэтому хорошо, что компилятор делает ее приятной и легкой для нас.

Для получения дополнительной информации см. « C # in Depth » или « LINQ в действии » , оба из которых охватывают эти темы.

181
ответ дан 23 November 2019 в 03:07
поделиться

Это позволяет выполнять дальнейшие запросы дальше по строке. Если, скажем, это выходит за границы службы, то пользователю этого объекта IQueryable будет разрешено делать с ним больше.

Например, если вы использовали ленивую загрузку с nhibernate, это могло бы привести к загрузке графа, когда / при необходимости.

1
ответ дан 23 November 2019 в 03:07
поделиться
Другие вопросы по тегам:

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