在使用 Linq 2 SQL 在示例应用程序中实现 AdventureWorks 数据库时,我遇到了一个问题,即 Linq 2 SQL 为我的 DBML 中定义的继承映射中的派生类型生成 SQL 语句的方式。
我的 DBML 中有两个实体,Person 和 PersonPhone(一个 Person 到多个 PersonPhone),没有定义任何继承映射(Person 将在后面的示例中成为继承基类)。如果我随后运行以下 Linq 语句,我注意到在进行跟踪时会按预期生成以下 SQL:
void Main()
{
this.DeferredLoadingEnabled = false;
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Person>(n => n.PersonPhones);
this.LoadOptions = dlo;
Person person = this.Persons.SingleOrDefault(n => n.BusinessEntityID == 291);
person.PersonPhones.Dump();
}
DECLARE @p0 Int = 291
SELECT [t0].[BusinessEntityID], [t0].[PersonType], [t0].[NameStyle], [t0].[Title], [t0].[FirstName], [t0].[MiddleName], [t0].[LastName], [t0].[Suffix], [t0].[EmailPromotion], [t0].[AdditionalContactInfo], [t0].[Demographics], [t0].[rowguid], [t0].[ModifiedDate], [t1].[BusinessEntityID] AS [BusinessEntityID2], [t1].[PhoneNumber], [t1].[PhoneNumberTypeID], [t1].[ModifiedDate] AS [ModifiedDate2], (
SELECT COUNT(*)
FROM [Person].[PersonPhone] AS [t2]
WHERE [t2].[BusinessEntityID] = [t0].[BusinessEntityID]
) AS [value]
FROM [Person].[Person] AS [t0]
LEFT OUTER JOIN [Person].[PersonPhone] AS [t1] ON [t1].[BusinessEntityID] = [t0].[BusinessEntityID]
WHERE [t0].[BusinessEntityID] = @p0
ORDER BY [t0].[BusinessEntityID], [t1].[PhoneNumber], [t1].[PhoneNumberTypeID]
结果是在单个语句中生成 SQL。请忽略这可能是低效的 SQL 的事实,我要说的是它在单个语句中运行。
但是,如果我在我的 DBML 中包含继承映射信息并定义一个名为 StoreContact(从 Person 派生)的新实体类型并运行完全相同的查询,我实际上会得到不同的结果,如下所示。在那两个 SQL 语句实际上运行。
DECLARE @p0 Int = 291
SELECT [t0].[PersonType], [t0].[BusinessEntityID], [t0].[NameStyle], [t0].[Title], [t0].[FirstName], [t0].[MiddleName], [t0].[LastName], [t0].[Suffix], [t0].[EmailPromotion], [t0].[AdditionalContactInfo], [t0].[Demographics], [t0].[rowguid], [t0].[ModifiedDate]
FROM [Person].[Person] AS [t0]
WHERE [t0].[BusinessEntityID] = @p0
GO
DECLARE @x1 Int = 291
SELECT [t0].[BusinessEntityID], [t0].[PhoneNumber], [t0].[PhoneNumberTypeID], [t0].[ModifiedDate]
FROM [Person].[PersonPhone] AS [t0]
WHERE [t0].[BusinessEntityID] = @x1
这有点问题,因为这将大大降低我们的应用程序的速度,因为在实现继承功能的情况下,Linq 2 SQL 需要对数据库进行重复调用。看起来拥有 OOP 模型确实是有代价的。
是否有解决此问题的方法可以使 SQL 在单个语句中运行?