我有一对多的关系。 (产品和数量中断定价)。在数据库级别,我无法在两个表之间创建关系。我将这两个表引入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中急切加载,我无法弄清楚这两个表之间的区别。
答案 0 :(得分:1)
我创建了一个VB控制台应用程序并在此处创建了架构。
此外 - 关系是PK - &gt; 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
答案 1 :(得分:0)
默认情况下,LINQ to SQL采用延迟绑定,这意味着它不会在需要之前查询数据库。这就是你得到多个查询的原因。
您可以采取一些措施来避免数据库上出现多次点击:
您可以在LINQ to SQL设计器中全局关闭延迟绑定。但是如果你的表有任何关系,那么你总是会执行JOINS。
您在LINQ查询中手动执行JOIN。如果执行此操作,则必须指定要在LINQ查询中返回哪些“字段”以返回JOINED数据。如果你这样做,那么你将返回一个匿名类型
注意: LINQ to SQL不支持LEFT JOINS。如果你google LINQ to SQL Left Joins,你会看到关于这个特定主题的大量信息
欢呼,祝你好运!答案 2 :(得分:0)
抓住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}
答案 3 :(得分:0)
我最终使用了实体框架,一切都很顺利。