【问题标题】:LINQ to SQL: Mapping a subset of an associationLINQ to SQL:映射关联的子集
【发布时间】:2009-01-09 10:35:35
【问题描述】:

在我们最初的开发过程中,我们并不担心扩展问题,只是让系统的基本骨架作为一个有凝聚力的整体工作。

我们现在正在研究细化屏幕,其中记录的数量将变得太大而无法显示。例如,我们有一个显示Parent 详细信息的页面,该页面当前涉及显示所有Child 记录。这是通过调用Parent 对象上的Children 属性来完成的(我们正在尝试开发一个富域)。我们想把它改成RecentChildren

问题是我找不到以任何方式限制EntitySet 返回的记录的方法。您可以对EntitySet 进行查询,但它会从数据库中检索所有Children,然后使用LINQ to Objects 对其进行过滤。显然这是非常低效的。

我们可以重构代码以删除 Children 属性的映射并从服务中检索它们,但我们希望尽可能将关联保留在域中。

有什么办法可以解决这个问题,还是我们必须查看不同的 ORM,例如 NHibernate?

【问题讨论】:

  • NHibernate 在什么方面是“正确的” ORM,而 LINQ to SQL 不是?
  • NHibernate 为一个缓存,能够做我在这里要求另一个

标签: .net linq linq-to-sql


【解决方案1】:

blogging about 我的LINQ to SQL 遇到问题后,一个叫Anders 的人向我指出了解决这个问题的方向。使用DataLoadOptions.AssociateWith

【讨论】:

    【解决方案2】:

    好吧,您可以不使用导航属性 - 即直接使用父 ID 并从子集中进行选择?

    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
    

    请注意,在这两种情况下,日期条件都会下放到数据库中。

    【讨论】:

    • 这与将任务推迟到我不想做的服务基本相同。
    【解决方案3】:

    将RecentChildren 属性添加到Parent 部分类。不要将其实现为 EntitySet。

    【讨论】:

      猜你喜欢
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多