簡體   English   中英

EF4代碼優先 - 瘋狂嵌套UNION ALL和重復的連接?

[英]EF4 code-first - insanely nested UNION ALL and duplicated joins?

我的“默認get方法”中有一個包含相當多包含的類,如下所示:

_dbContext.Users
    .Include(c => c.PublicContact)
    .Include(c => c.PrivateContact)
    .Include(c => c.Product)
    .Include(c => c.Languages)
    .Include(c => c.Categories)
    .Include(c => c.Memberships)
    .Include(c => c.SearchWords)
    .Include(c => c.Referals)
    .Include(c => c.Files)
    .Include(c => c.Articles);

用戶從BaseEntity繼承,如下所示:

public class BaseEntity : IEntity
{
    public BaseEntity()
    {
        DateTime createdTime = DateTime.Now;
        Created = createdTime;
        Modified = createdTime;
    }

    public int Id { get; set; }
    public byte[] Timestamp { get; set; }
    public DateTime Created { get; set; }
    public DateTime Modified { get; set; }
}

當對此進行查詢時,嘗試查找特定用戶需要幾秒鍾(實際上差不多一分鍾) - 所以我添加了一個分析器,幾乎摔倒在椅子上觀察實際的SQL生成...

它是一個loooooooong SQL - 我試着將它粘貼到gmail中給朋友發郵件,但gmail(在chrome中)讓我感到不安。 不用說,我不會在這里粘貼所有內容,只是給你一個錯誤的主題。

它開頭是這樣的:

DECLARE @p__linq__0 int = 1,
        @p__linq__1 int = 153

SELECT 
[UnionAll6].[C2] AS [C1], 
[UnionAll6].[C3] AS [C2], 
[UnionAll6].[C4] AS [C3],
...
[UnionAll6].[C121] AS [C121], 
[UnionAll6].[C122] AS [C122], 
[UnionAll6].[C123] AS [C123]
FROM  (SELECT 
        [UnionAll5].[C1] AS [C1], 
        [UnionAll5].[C2] AS [C2], 
        [UnionAll5].[C3] AS [C3], 

正如你所看到的,它從'UnionAll6'中選擇,因為它將這些瘋狂的選擇嵌套在6(SIX!)級別中。

當我查看內部嵌套(UnionAll1)時,我發現它實際上已經嵌套得更深 - 這次它從名為[Limit1],[Limit2]等的東西中進行選擇,其中它選擇了正確名稱的字段,就像這樣' [Limit1]。[EmailAddress] AS [EmailAddress]'。 在這個級別(連同選擇Limit1.EmailAddress)我也發現:

CAST(NULL AS varchar(1)) AS [C2], 
CAST(NULL AS datetime2) AS [C3], 
CAST(NULL AS varchar(1)) AS [C4], 

所有這些選擇實際上都是這次再次嵌套如下所示:

(SELECT TOP (1) 
    [Extent1].[Id] AS [Id], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[EmailAddress] AS [EmailAddress], 
    [Extent1].[LongDescription] AS [LongDescription], 
    [Extent1].[Modified] AS [Modified], 

這個級別似乎是最后一個,並且執行了一些重的左外連接(實際上有一些是針對額外的嵌套選擇)。 這是UNION ALL和其他一些廢話,看起來非常相似。

我有一些多對多的關系 - 它們在配置中定義如下:

public class UsersConfiguration : EntityBaseConfiguration<Users>
{
    public UsersConfiguration()
    {
        HasMany(c => c.Languages).WithMany();
        HasMany(c => c.Categories).WithMany();
    }
}

public class EntityBaseConfiguration<T> : EntityConfiguration<T> where T : BaseEntity
{
    public EntityBaseConfiguration()
    {
        HasKey(e => e.Id);
        Property(e => e.Id).IsIdentity();
        Property(e => e.Timestamp).IsConcurrencyToken()
            .IsRequired()
            .HasStoreType("timestamp")
            .StoreGeneratedPattern = StoreGeneratedPattern.Computed;
        Property(e => e.Created)
            .StoreGeneratedPattern = StoreGeneratedPattern.None;
        Property(e => e.Modified)
            .StoreGeneratedPattern = StoreGeneratedPattern.None;
    }
}

我正在反對CTP 4'v4.0.30319'並且我想升級,但這樣做會打破很多東西 - 我的配置不起作用,因為似乎已經改變了很多。 我會通過升級重寫整個東西,如果這解決了這個瘋狂的嵌套問題,但我不知道它會怎么樣?

好的,所以我決定不從基礎繼承,而是實現一個具有我的基礎相同屬性的接口。 這讓我打破DRY,因為我需要在我的所有實體上重新實現所有相同的屬性。 我可以保持對配置的繼承,所以這並不全是壞事。

生成的SQL現在看起來更好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM