我在数据库中有一个简单的Parent Child表
CREATE TABLE [Parent](
[Id] [int] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](256) NOT NULL)
ALTER TABLE [Parent] ADD CONSTRAINT [PK_Parent_Id] PRIMARY KEY ([Id])
CREATE TABLE [Child](
[Id] [int] IDENTITY(1,1) NOT NULL,
[ParentId] [int] NOT NULL,
[Name] [nvarchar](256) NOT NULL)
ALTER TABLE [Child] ADD CONSTRAINT [PK_Child_Id] PRIMARY KEY ([Id])
ALTER TABLE [Child] ADD CONSTRAINT [FK_Child_Parent_ID]
FOREIGN KEY([ParentId]) REFERENCES [Parent] ([Id])
我在其中的数据是
父表
Id Name
1 John
子表
Id ParentId Name
1 1 Mike
2 1 Jake
3 1 Sue
4 1 Liz
这些表使用Visual Studio中的Linq-2-SQL设计器映射到Parent
和Child
C#对象,没有非标准选项。
我做了一个简单的测试程序,用父母查询所有孩子
public partial class Parent
{
static int counter = 0;
//default OnCreated created by the linq to sql designer
partial void OnCreated()
{
Console.WriteLine(string.Format("CreatedParent {0} hashcode={1}",
++counter , GetHashCode()));
}
}
class Program
{
static void Main(string[] args)
{
using (var db = new SimpleDbDataContext())
{
DataLoadOptions opts = new DataLoadOptions();
opts.LoadWith<Child>(c => c.Parent);
db.LoadOptions = opts;
var allChildren = db.Childs.ToArray();
foreach (var child in allChildren)
{
Console.WriteLine(string.Format("Parent name={0} hashcode={1}",
child.Parent.Name, child.Parent.GetHashCode()));
}
}
}
}
上述程序的输出是
CreatedParent 1 hashcode=53937671
CreatedParent 2 hashcode=9874138
CreatedParent 3 hashcode=2186493
CreatedParent 4 hashcode=22537358
Parent name=John hashcode=53937671
Parent name=John hashcode=53937671
Parent name=John hashcode=53937671
Parent name=John hashcode=53937671
正如您所看到的,为数据库中的每个Parent
创建了一个Child
对象,最终只能被丢弃。
问题:
Parent
个对象?Parent
个对象?答案 0 :(得分:12)
这是方式的副作用,LoadWith
已实施。 LINQ to SQL将您的查询内部转换为:
from c in children
select { Child = c, Parent = c.Parent }
如您所见,我们为每个孩子(内部联接)加载一次Parent。由于身份图,此效果通常不可见。 ORM确保实体对象永远不会被(表,主键)复制。当您进行更新时,这会派上用场。
LINQ to SQL读取从服务器返回的结果集(它包含相同的父N次!)并将其具体化为对象。只有在完成实现后,身份映射才能完成其工作并丢弃重复的父实例。
同样的效果适用于多次返回同一实体的所有查询。