LINQ to SQL: отображение подмножества ассоциации - PullRequest
3 голосов
/ 09 января 2009

Во время нашей первоначальной разработки мы не беспокоились о масштабировании, а просто заставили систему работать как единое целое.

Сейчас мы смотрим на уточняющие экраны, где количество записей станет слишком большим для отображения. Например, у нас есть страница для отображения сведений о Parent, которая в настоящее время включает отображение всех записей Child. Это делается путем вызова свойства Children объекта Parent (мы пытаемся разработать расширенный домен). Мы хотим изменить это на RecentChildren.

Проблема в том, что я не могу найти способ каким-либо образом ограничить записи, возвращаемые EntitySet. Вы можете выполнить запрос к EntitySet, но он извлекает все Children из базы данных и затем использует LINQ to Objects для его фильтрации. Очевидно, это очень неэффективно.

Мы могли бы реструктурировать код, чтобы удалить сопоставление свойства Children и получить их из службы, но мы хотели бы сохранить связь в домене, если это возможно.

Есть ли способ обойти это или нам нужно взглянуть на другой ORM, такой как NHibernate?

Ответы [ 3 ]

3 голосов
/ 14 января 2009

После публикации в блоге о моих проблем LINQ to SQL, парень по имени Андерс указал мне в направлении решения этой проблемы. Использование DataLoadOptions.AssociateWith .

1 голос
/ 09 января 2009

Ну, вы можете просто не использовать свойство навигации - то есть напрямую использовать родительский идентификатор и выбрать из дочернего набора?

т.е.

int id = parent.ParentID;
var qry = from child in db.Children
          where child.ParentID = id && child.Date > whatever
          select child;

Я также подозреваю, что выполнение SelectMany с использованием свойств навигации внутри запроса будет работать:

using System;
using System.Linq;
using ConsoleApplication5;


class Program
{
    static void Main(string[] args)
    {
        string id;
        using (var ctx = new DataClasses1DataContext())
        {
            id = ctx.Customers.Select(x => x.CustomerID).First();
        }
        DateTime cutoff = DateTime.Today.AddMonths(-2);

        using (var ctx = new DataClasses1DataContext())
        {
            // parent id
            ctx.Log = Console.Out;
            var qry = from o in ctx.Orders
                      where o.CustomerID == id
                        && o.OrderDate > cutoff
                      select o;
            foreach (var order in qry)
            {
                Console.WriteLine(order.OrderID);
            }
        }

        using (var ctx = new DataClasses1DataContext())
        {
            // navigation property in query
            ctx.Log = Console.Out;
            var qry = from c in ctx.Customers
                      where c.CustomerID == id
                      from o in c.Orders
                      where o.OrderDate > cutoff
                      select o;
            foreach (var order in qry)
            {
                Console.WriteLine(order.OrderID);
            }
        }
    }
}

TSQL (извините за формат - дамп консоли!):

SELECT [t0].[OrderID], [t0].[CustomerID], [t0].[EmployeeID], [t0].[OrderDate], [
t0].[RequiredDate], [t0].[ShippedDate], [t0].[ShipVia], [t0].[Freight], [t0].[Sh
ipName], [t0].[ShipAddress], [t0].[ShipCity], [t0].[ShipRegion], [t0].[ShipPosta
lCode], [t0].[ShipCountry]
FROM [dbo].[Orders] AS [t0]
WHERE ([t0].[CustomerID] = @p0) AND ([t0].[OrderDate] > @p1)
-- @p0: Input NVarChar (Size = 5; Prec = 0; Scale = 0) [ALFKI]
-- @p1: Input DateTime (Size = 0; Prec = 0; Scale = 0) [09/11/08 00:00:00]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1

SELECT [t1].[OrderID], [t1].[CustomerID], [t1].[EmployeeID], [t1].[OrderDate], [
t1].[RequiredDate], [t1].[ShippedDate], [t1].[ShipVia], [t1].[Freight], [t1].[Sh
ipName], [t1].[ShipAddress], [t1].[ShipCity], [t1].[ShipRegion], [t1].[ShipPosta
lCode], [t1].[ShipCountry]
FROM [dbo].[Customers] AS [t0], [dbo].[Orders] AS [t1]
WHERE ([t1].[OrderDate] > @p0) AND ([t0].[CustomerID] = @p1) AND ([t1].[Customer
ID] = [t0].[CustomerID])
-- @p0: Input DateTime (Size = 0; Prec = 0; Scale = 0) [09/11/08 00:00:00]
-- @p1: Input NVarChar (Size = 5; Prec = 0; Scale = 0) [ALFKI]
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1

Обратите внимание, что в обоих случаях условие даты отправлено в базу данных.

0 голосов
/ 10 января 2009

Добавьте свойство RecentChildren в частичный класс Parent. Не используйте его как EntitySet.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...