gpt4 book ai didi

sql-server - 对非常简单的 EF 查询进行额外联接以实现 1-1 关系

转载 作者:行者123 更新时间:2023-12-02 13:38:23 25 4
gpt4 key购买 nike

我在一个全新的项目上有这个简单的模型:

class A
{
public int Id { get; set; }
public B B { get; set; }
}

class B
{
public int Id { get; set; }
public string Text { get; set; }
}

class C
{
public int Id { get; set; }
public B B { get; set; }
}

映射是:

modelBuilder.Entity<A>().HasOptional(x => x.B).WithOptionalDependent();
modelBuilder.Entity<C>().HasOptional(x => x.B).WithOptionalDependent();

我正在运行此查询:

db.As.Include(a => a.B).Where(a => a.B.Text == "10").FirstOrDefault();

其中db.As是A的DbSet。

它生成以下sql

SELECT TOP (1)
[Extent1].[Id] AS [Id],
[Join8].[Id1] AS [Id1],
[Join8].[Text] AS [Text],
[Join11].[Id2] AS [Id2],
[Join14].[Id3] AS [Id3]
FROM [dbo].[A] AS [Extent1]
INNER JOIN (SELECT [Extent2].[Text] AS [Text], [Extent3].[Id] AS [Id4]
FROM [dbo].[B] AS [Extent2]
LEFT OUTER JOIN [dbo].[A] AS [Extent3] ON ([Extent3].[B_Id] IS NOT NULL) AND ([Extent2].[Id] = [Extent3].[B_Id])
LEFT OUTER JOIN [dbo].[C] AS [Extent4] ON ([Extent4].[B_Id] IS NOT NULL) AND ([Extent2].[Id] = [Extent4].[B_Id]) ) AS [Join2] ON [Extent1].[Id] = [Join2].[Id4]
INNER JOIN (SELECT [Extent5].[Text] AS [Text], [Extent6].[Id] AS [Id5]
FROM [dbo].[B] AS [Extent5]
LEFT OUTER JOIN [dbo].[A] AS [Extent6] ON ([Extent6].[B_Id] IS NOT NULL) AND ([Extent5].[Id] = [Extent6].[B_Id])
LEFT OUTER JOIN [dbo].[C] AS [Extent7] ON ([Extent7].[B_Id] IS NOT NULL) AND ([Extent5].[Id] = [Extent7].[B_Id]) ) AS [Join5] ON [Extent1].[Id] = [Join5].[Id5]
LEFT OUTER JOIN (SELECT [Extent8].[Id] AS [Id1], [Extent8].[Text] AS [Text], [Extent9].[Id] AS [Id6]
FROM [dbo].[B] AS [Extent8]
LEFT OUTER JOIN [dbo].[A] AS [Extent9] ON ([Extent9].[B_Id] IS NOT NULL) AND ([Extent8].[Id] = [Extent9].[B_Id])
LEFT OUTER JOIN [dbo].[C] AS [Extent10] ON ([Extent10].[B_Id] IS NOT NULL) AND ([Extent8].[Id] = [Extent10].[B_Id]) ) AS [Join8] ON [Extent1].[Id] = [Join8].[Id6]
LEFT OUTER JOIN (SELECT [Extent12].[Id] AS [Id2]
FROM [dbo].[B] AS [Extent11]
LEFT OUTER JOIN [dbo].[A] AS [Extent12] ON ([Extent12].[B_Id] IS NOT NULL) AND ([Extent11].[Id] = [Extent12].[B_Id])
LEFT OUTER JOIN [dbo].[C] AS [Extent13] ON ([Extent13].[B_Id] IS NOT NULL) AND ([Extent11].[Id] = [Extent13].[B_Id]) ) AS [Join11] ON [Extent1].[Id] = [Join11].[Id2]
LEFT OUTER JOIN (SELECT [Extent15].[Id] AS [Id7], [Extent16].[Id] AS [Id3]
FROM [dbo].[B] AS [Extent14]
LEFT OUTER JOIN [dbo].[A] AS [Extent15] ON ([Extent15].[B_Id] IS NOT NULL) AND ([Extent14].[Id] = [Extent15].[B_Id])
LEFT OUTER JOIN [dbo].[C] AS [Extent16] ON ([Extent16].[B_Id] IS NOT NULL) AND ([Extent14].[Id] = [Extent16].[B_Id]) ) AS [Join14] ON [Extent1].[Id] = [Join14].[Id7]
WHERE (N'10' = [Join2].[Text]) AND ([Join5].[Text] IS NOT NULL)

这对我来说似乎很复杂。它甚至与 C “连接”,我没有从 A 或 B 引用它,并且不包含在查询中。

现在的情况是:我们有一个大型项目,其中有一些非常复杂的模型,我们遇到了一些性能问题,当我们分析查询时,我们发现有些查询需要“包含”很多实体,并且它们生成超过3k行的SQL。

我们的映射或配置有问题吗?我们禁用了延迟加载和代理创建。

最佳答案

我没有真正的答案给你,但如果有相同的规范,我会写:

modelBuilder.Entity<A>().HasOptional(x => x.B).WithMany();
modelBuilder.Entity<C>().HasOptional(x => x.B).WithMany();

它提供与您相同的数据库架构。

我为什么要这样做:因为我经常思考“我想要什么模式?”,根据我的实践,对于这个模式,代码就是上面的代码。

顺便说一句:ctx.Set<A>().Include(x => x.B).Where(x => x.B.Text == "10").Select(x => x) 的查询结果是:

SELECT
[Extent1].[Id] AS [Id],
[Extent3].[Id] AS [Id1],
[Extent3].[Text] AS [Text]
FROM
[dbo].[A] AS [Extent1]
INNER JOIN [dbo].[B] AS [Extent2] ON [Extent1].[B_Id] = [Extent2].[Id]
LEFT OUTER JOIN [dbo].[B] AS [Extent3] ON [Extent1].[B_Id] = [Extent3].[Id]
WHERE
N'10' = [Extent2].[Text]

但仍然在这里:为什么要extend3?

因为Extend2允许过滤没有B的A:即inner join ... extend2是一个where(真的很清楚,不是吗?)

关于sql-server - 对非常简单的 EF 查询进行额外联接以实现 1-1 关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30194004/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com