OData с настраиваемым построителем моделей, подключенным к платформе Entity, создает дублирующее левое соединение - PullRequest
0 голосов
/ 29 мая 2020

У меня проблема, которую я сначала не заметил, потому что моя машина для разработки была быстрой, а мой набор тестов небольшой. Поэтому я создал небольшой демонстрационный проект, потому что проблему легко воспроизвести, если вы знаете, где искать. Вы можете найти его на моем github https://github.com/PhbsSmn/ExpandIssue

Я пробую простую команду odata:

https://localhost:5001/odata/MasterTables?$filter=Id eq 4&$expand=Childs

Здесь ничего особенного, я запрашиваю только записи, которые равны до id 4 и разверните его дочерние элементы

Мой конструктор моделей, в котором я настраиваю навигацию:

    public class ExpandIssueModelBuilder
    {
        public IEdmModel GetEdmModel(IServiceProvider serviceProvider)
        {
            const int defaultPageSize = 100;

            var builder = new ODataConventionModelBuilder(serviceProvider)
            {
                Namespace = "ExpandIssue"
            };

            var masterTable = builder.EntitySet<MasterTableDetail>("MasterTables");
            masterTable.EntityType.Page(null, defaultPageSize);
            masterTable.HasManyBinding(m => m.Childs, "ChildTableInfo");

            return builder.GetEdmModel();
        }
    }

Мой контроллер, где я сопоставляю entityframework с моделью odata

    [Produces("application/json")]
    public class MasterTablesController : ODataController
    {
        //...

        [EnableQuery(EnableCorrelatedSubqueryBuffering = true, EnsureStableOrdering = false)]
        public IQueryable<MasterTableDetail> Get()
        {
            return _context.MasterTable.Select(m => new MasterTableDetail
            {
                Id = m.Id,
                Name = m.Name,
                Childs = m.ChildTable.Select(c => new ChildTableInfo
                {
                    Id = c.Id,
                    Created = c.Created,
                    Value = c.Value
                })
            }).OrderBy(m => m.Id);

        }
    }

Я не думаю, что делаю какие-то странные вещи, кроме того, что не хочу раскрывать свою модель базы данных.

Когда я открываю профилировщик SQL, я вижу следующий запрос, созданный, когда Команда odata выполняется:

    DECLARE @__TypedProperty_2 nvarchar(4000) = N'22bfc7f7-1f8a-4a92-b56b-c25cbb0742bd'
    DECLARE @__TypedProperty_3 int = 101
    DECLARE @__TypedProperty_0 int = 4

    SELECT
        [t].[Id], [t].[Name], 
        [c].[Id], [c].[Created], [c].[Value], @__TypedProperty_2,
        [c0].[Id], [c0].[Created], [c0].[Value], CAST(1 AS bit)
    FROM
        (SELECT TOP(@__TypedProperty_3) [m].[Id], [m].[Name]
         FROM [MasterTable] AS [m]
         WHERE [m].[Id] = @__TypedProperty_0
         ORDER BY [m].[Id]) AS [t]
        LEFT JOIN [ChildTable] AS [c] ON [t].[Id] = [c].[MasterTableId]
        LEFT JOIN [ChildTable] AS [c0] ON [t].[Id] = [c0].[MasterTableId]
    ORDER BY
        [t].[Id], [c].[Id], [c0].[Id]

Это было не то, что я ожидал, когда это выполняется. Результат в строках 1.048.576, которые в конечном итоге будут уменьшены до 1024. Я забыл что-то настроить, чтобы я вместо этого можно получить такой запрос:

    DECLARE @__TypedProperty_2 nvarchar(4000) = N'22bfc7f7-1f8a-4a92-b56b-c25cbb0742bd'
    DECLARE @__TypedProperty_3 int = 101
    DECLARE @__TypedProperty_0 int = 4

    SELECT
        [t].[Id], [t].[Name], 
        [c].[Id], [c].[Created], [c].[Value], @__TypedProperty_2,
        CAST(1 AS bit)
    FROM
        (SELECT TOP(@__TypedProperty_3) [m].[Id], [m].[Name]
         FROM [MasterTable] AS [m]
         WHERE [m].[Id] = @__TypedProperty_0
         ORDER BY [m].[Id]) AS [t]
        LEFT JOIN [ChildTable] AS [c] ON [t].[Id] = [c].[MasterTableId]
    ORDER BY
        [t].[Id], [c].[Id]

Надеюсь, кто-нибудь сможет мне помочь с этим, мне действительно нравится сила, которую дает мне функция расширения, но это болезненный вопрос.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...