【问题标题】:LINQ to SQL: inner join with manual association on SQL 2000LINQ to SQL:在 SQL 2000 上使用手动关联进行内部连接
【发布时间】:2010-10-05 12:45:53
【问题描述】:

我有两张表处于一对多关系中。 (产品和数量打破定价)。在数据库级别,我无法在两个表之间创建关系。我将这两个表带入 LINQ 并手动创建了关联。

我需要做一个大的 LINQ 查询并连接表。我的问题是它没有使用连接来获取数据。 LINQ 在主表上使用 1 次选择,然后为该主表中的每一行选择 1 次。

Dim db As New LSSStyleDataContext(connString)

Dim options As New DataLoadOptions()
options.LoadWith(Function(c As commerce_product) c.commerce_qty_breaks)
db.LoadOptions = options

Dim dbProducts = (From prods In db.commerce_products).ToList

对为什么会这样有什么想法吗?谢谢! 保罗

编辑:这是两张表:

CREATE TABLE [dbo].[commerce_product](
    [pf_id] [int] NOT NULL,
    [name] [varchar](500) COLLATE SQL_Latin1_General_CP1_CI_AS         
    [description] [text] COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
    [restricted] [varchar](5) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
   CONSTRAINT [PK_commerce_product_1] PRIMARY KEY NONCLUSTERED 
 (
    [pf_id] ASC
  ) ON [PRIMARY]
  ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

还有另一张桌子:

CREATE TABLE [dbo].[commerce_qty_break](
    [pf_id] [int] NOT NULL,
    [sku] [varchar](100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
    [qty] [int] NOT NULL,
    [list_price] [int] NOT NULL,
    [break_id] [int] NOT NULL,
    CONSTRAINT [PK_commerce_qty_break] PRIMARY KEY CLUSTERED 
    (
    [pf_id] ASC,
    [qty] ASC,
    [break_id] ASC
    ) ON [PRIMARY]
    ) ON [PRIMARY]

DBML 很简单,只有两个表。我在两个表之间创建了一个关联,“commerce_product”是父表,“commerce_qty_break”是由“PF_ID”加入的子表。

我可以这样写:

Dim dbproducts = From prods In db.commerce_products _
    Join qtys In db.commerce_qty_breaks On prods.pf_id Equals qtys.pf_id _
    Select prods

我看到它加入了查询中的表,但是一旦我尝试旋转“qty_breaks”,它就会开始执行选择以获取该信息。

我完全被难住了。

编辑 2:这是 DBML:

<?xml version="1.0" encoding="utf-8"?>
<Database Name="LSScommerceDB_DevB" Class="LSSStyleDataContext" xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">
  <Connection Mode="AppSettings" ConnectionString="***" SettingsObjectName="HSLPriceUpdate.My.MySettings" SettingsPropertyName="LSScommerceDB_DevBConnectionString" Provider="System.Data.SqlClient" />
  <Table Name="dbo.commerce_product" Member="commerce_products">
    <Type Name="commerce_product">
      <Column Name="pf_id" Type="System.Int32" DbType="Int NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
      <Column Name="name" Type="System.String" DbType="VarChar(500)" CanBeNull="true" />
      <Column Name="description" Type="System.String" DbType="Text" CanBeNull="true" UpdateCheck="Never" />
      <Column Name="list_price" Type="System.Int32" DbType="Int" CanBeNull="true" />
      <Column Name="image_file" Type="System.String" DbType="VarChar(255)" CanBeNull="true" />
      <Column Name="image_width" Type="System.Int32" DbType="Int" CanBeNull="true" />
      <Column Name="image_height" Type="System.Int32" DbType="Int" CanBeNull="true" />
      <Column Name="sale_price" Type="System.Int32" DbType="Int" CanBeNull="true" />
      <Column Name="sale_start" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
      <Column Name="sale_end" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
      <Column Name="attr_label1" Type="System.String" DbType="VarChar(100)" CanBeNull="true" />
      <Column Name="attr_label2" Type="System.String" DbType="VarChar(100)" CanBeNull="true" />
      <Column Name="attr_label3" Type="System.String" DbType="VarChar(100)" CanBeNull="true" />
      <Column Name="attr_label4" Type="System.String" DbType="VarChar(100)" CanBeNull="true" />
      <Column Name="attr_label5" Type="System.String" DbType="VarChar(100)" CanBeNull="true" />
      <Column Name="sku" Type="System.String" DbType="VarChar(100)" CanBeNull="true" />
      <Column Name="UOM" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
      <Column Name="Sell_Pack" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
      <Column Name="mfg_model_number" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
      <Column Name="mfg_id" Type="System.Int32" DbType="Int" CanBeNull="true" />
      <Column Name="logo_file" Type="System.String" DbType="VarChar(255)" CanBeNull="true" />
      <Column Name="drop_ship" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
      <Column Name="lead_time" Type="System.Int32" DbType="Int" CanBeNull="true" />
      <Column Name="hazard_flag" Type="System.String" DbType="VarChar(50)" CanBeNull="true" />
      <Column Name="publish_date" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
      <Column Name="restricted" Type="System.String" DbType="VarChar(5)" CanBeNull="true" />
      <Association Name="commerce_product_commerce_qty_break" Member="commerce_qty_breaks" ThisKey="pf_id" OtherKey="pf_id" Type="commerce_qty_break" />
    </Type>
  </Table>
  <Table Name="dbo.commerce_qty_break" Member="commerce_qty_breaks">
    <Type Name="commerce_qty_break">
      <Column Name="pf_id" Type="System.Int32" DbType="Int NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
      <Column Name="sku" Type="System.String" DbType="VarChar(100) NOT NULL" CanBeNull="false" />
      <Column Name="qty" Type="System.Int32" DbType="Int NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
      <Column Name="list_price" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
      <Column Name="sale_price" Type="System.Int32" DbType="Int" CanBeNull="true" />
      <Column Name="sale_start" Type="System.DateTime" DbType="DateTime NOT NULL" CanBeNull="false" />
      <Column Name="sale_end" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
      <Column Name="break_id" Type="System.Int32" DbType="Int NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
      <Association Name="commerce_product_commerce_qty_break" Member="commerce_product" ThisKey="pf_id" OtherKey="pf_id" Type="commerce_product" IsForeignKey="true" />
    </Type>
  </Table>
</Database>

编辑 3:显然这只是 SQL 2000 中的一个问题。SQL 2008 工作正常。我有其他表在 SQL 2000 中进行预加载,但我不知道这两个表之间有什么区别。

【问题讨论】:

  • 您能发布您的 DBML 和实体定义的详细信息吗?
  • 我已更新问题以包含更多详细信息。
  • 你能把 DBML 也弹出来吗?塔
  • 给你!感谢您查看此内容!

标签: asp.net sql vb.net linq linq-to-sql


【解决方案1】:

我创建了一个 VB 控制台应用程序并按照您在此处创建的架构创建了它。

另外 - 关系是 PK -> PK 所以这是否意味着它应该是一对一的关系?

我在表格中分别填充了一行(见下文)并运行了您在上面列出的代码。我运行了 SQL Profiler,它只查询了一次:

SELECT [t0].[pf_id], [t0].[name], [t0].[description], [t0].[restricted], 
[t1].[pf_id] AS [pf_id2], [t1].[sku], [t1].[qty], [t1].[list_price], 
[t1].[break_id], (
SELECT COUNT(*)
FROM [dbo].[commerce_qty_break] AS [t2]
WHERE [t2].[pf_id] = [t0].[pf_id]
) AS [value]
FROM [dbo].[commerce_product] AS [t0]
LEFT OUTER JOIN [dbo].[commerce_qty_break] AS [t1] ON [t1].[pf_id] = [t0].[pf_id]
ORDER BY [t0].[pf_id], [t1].[qty], [t1].[break_id]

我想确保数据选项强制进行深度加载,所以我添加了一些额外的代码 - 这是我使用的完整代码(并且只跟踪了上面的单个查询):

Dim options As New DataLoadOptions()

options.LoadWith(Function(c As commerce_product) c.commerce_qty_breaks)
db.LoadOptions = options

Dim dbProducts = (From prods In db.commerce_products).ToList

Dim dbProduct = dbProducts.First().commerce_qty_breaks
Dim x = dbProduct.First().list_price

这是测试数据:

INSERT INTO [Test].[dbo].[commerce_product] ([pf_id],[name],[description],[restricted]) VALUES (1,'Test','Test','Test')
GO
INSERT INTO [Test].[dbo].[commerce_qty_break] ([pf_id],[sku],[qty],[list_price],[break_id]) VALUES (1,'22',1,1,1)
GO

【讨论】:

  • 这是针对 SQL Server 2008 从 Visual Studio 2008 SP 1 运行的(并在 .Net Framework 3.5 上运行)
  • 有趣...我将数据库复制到 SQL 2008 服务器,它工作得很好!该数据库目前位于 SQL 2000 上。为什么这很重要?我认为 linq to sql 的唯一区别是“take”方法?
  • 是的,我的理解也一样。我将它指向一个 SQL 2000 db,看看是否得到相同的结果。
【解决方案2】:

嘿,我不确定我是否完全理解你的问题,但这里有一些信息,

默认情况下,LINQ to SQL 采用惰性绑定,这意味着它不会在需要时查询数据库。这就是您收到多个查询的原因。

您可以采取一些措施来避免多次点击数据库:

  1. 您可以在 LINQ to SQL 设计器中全局关闭延迟绑定。但是,如果您的表有任何关系,您将始终执行 JOINS。

  2. 您在 LINQ 查询中手动执行 JOIN。如果这样做,则必须指定要在 LINQ 查询中返回的“字段”以取回 JOINED 数据。如果你这样做,那么你将返回一个匿名类型

注意: LINQ to SQL 不支持左连接。如果你用谷歌搜索 LINQ to SQL Left Joins,你会看到很多关于这个特定主题的信息

干杯,祝你好运!

【讨论】:

  • 延迟加载不适用于他的情况,因为他使用的是DataLoadOptions
  • 我的建议是否仍然适用,还是发生了其他事情?
  • 如果没有看到 DBML/Entity 定义就很难说 - 不清楚他是如何手动创建关联的。如果他试图返回一个子集,我会同意#2 - 取决于他如何建模它
  • hmm...LINQ To SQL,你一定会喜欢它
  • Rob,这正是我难过的原因。
【解决方案3】:

去抢LINQPad。玩这样的东西非常棒。

你尝试过这样的事情吗?

Dim dbproducts = From prods In db.commerce_products _
    Join qtys In db.commerce_qty_breaks On prods.pf_id Equals qtys.pf_id _
    Select new {prods, qtys}

【讨论】:

    【解决方案4】:

    我最终使用了实体框架,一切都很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-24
      • 1970-01-01
      • 2011-03-11
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      相关资源
      最近更新 更多