Веб-API возвращает только некоторые связанные объекты - PullRequest
0 голосов
/ 05 марта 2019

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

Во-первых, немного информации: я не разработчик.У меня нет обучения, я только учусь, делая и используя огромные ресурсы, такие как StackOverflow.

Теперь к данной проблеме.Я не уверен, связано ли это с Entity Framework Core, Asp.net Core или React (хотя я уверен, что это не связано с React, я также включу это).

Я сократил свои моделидля краткости.

Модели моей сущности:

public class TableA
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

public class TableB
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

public class TableC
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

public class TableD
{
    public Guid Id { get; set; }
    public Guid TableAID { get; set; }
    public Guid TableBID { get; set; }
    public Guid TableCID { get; set; }
    public string Ticket { get; set; }

    public TableA TableA { get; set; }
    public TableB TableB { get; set; }
    public TableC TableC { get; set; }
}

Пока все хорошо, все в этой точке работает как задумано.Сущность TableD работает как таблица ручного связывания.

Мой контроллер Web API (это влияет только на действие GET, что я вижу во время тестирования):

[HttpGet]
public async Task<IActionResult> GetTableDAsync()
{
    var table = await _context.TableD
        .Include(ta => ta.TableA)
        .Include(tb => tb.TableB)
        .Include(tc => tc.TableC)
        .ToListAsync();
    return Ok(table);
}

Скажитечто я 7 раз опубликовал в своем API, чтобы мое действие GET вернуло массив с 4 объектами, вот где все становится интересным.Связанный объект для TableC возвращает только 2 из 4 раз:

[
{
    "id": "Guid",
    "tableAID": "e16ec113-7e41-4c41-a01e-2340ad1b79c8", //this corresponds to value in tableB
    "tableBID": "9ca5fa0f-663f-4788-cda1-08d688404921", //this corresponds to value in TableA
    "tableCID": "97a825ff-e465-46bc-8af6-2e8f8465323e", //this corresponds to value in TableC
    "tableA": {
        "id": "e16ec113-7e41-4c41-a01e-2340ad1b79c8",
        "name": "name"
    },
    "ticket": 123456,
    "tableB": {
        "id": "9ca5fa0f-663f-4788-cda1-08d688404921",
        "firstName": "name"
    },
    "tableC": {
        "id": "97a825ff-e465-46bc-8af6-2e8f8465323e",
        "name": "name"
    }
},
{
    "id": "Guid",
    "tableAID": "e16ec113-7e41-4c41-a01e-2340ad1b79c9", //this corresponds to value in tableB
    "tableBID": "9ca5fa0f-663f-4788-cda1-08d688404922", //this corresponds to value in TableA
    "tableCID": "97a825ff-e465-46bc-8af6-2e8f8465323f", //this corresponds to value in TableC
    "tableA": {
        "id": "e16ec113-7e41-4c41-a01e-2340ad1b79c9",
        "name": "name"
    },
    "ticket": 123456,
    "tableB": {
        "id": "9ca5fa0f-663f-4788-cda1-08d688404922",
        "firstName": "name"
    },
    "tableC": null
},
{
    "id": "Guid",
    "tableAID": "e16ec113-7e41-4c41-a01e-2340ad1b79c0", //this corresponds to value in tableB
    "tableBID": "9ca5fa0f-663f-4788-cda1-08d688404923", //this corresponds to value in TableA
    "tableCID": "97a825ff-e465-46bc-8af6-2e8f84653231", //this corresponds to value in TableC
    "tableA": {
        "id": "e16ec113-7e41-4c41-a01e-2340ad1b79c0",
        "name": "name"
    },
    "ticket": 123456,
    "tableB": {
        "id": "9ca5fa0f-663f-4788-cda1-08d688404923",
        "firstName": "name"
    },
    "tableC": {
        "id" : "97a825ff-e465-46bc-8af6-2e8f84653231",
        "name": "name"
    }
},
{
    "id": "Guid",
    "tableAID": "e16ec113-7e41-4c41-a01e-2340ad1b79c1", //this corresponds to value in tableB
    "tableBID": "9ca5fa0f-663f-4788-cda1-08d688404924", //this corresponds to value in TableA
    "tableCID": "97a825ff-e465-46bc-8af6-2e8f84653232", //this corresponds to value in TableC
    "tableA": {
        "id": "e16ec113-7e41-4c41-a01e-2340ad1b79c1",
        "name": "name"
    },
    "ticket": 123456,
    "tableB": {
        "id": "9ca5fa0f-663f-4788-cda1-08d688404924",
        "firstName": "name"
    },
    "tableC": null
}

]

И в моем интерфейсе SPA (это не адаптировано к примерам кода, но используется только для визуализации), Я хотел бы обратить ваше внимание на выделенные поля.Все поля имеют значения, которые должны возвращать значения.Image from Frontend Если я запускаю необработанный SQL-запрос, сгенерированный Entity Framework (из отладки в Visual Studio), значения возвращаются, как и ожидалось.

Кто-нибудь из вас знает, что происходит?и почему, казалось бы, наугад, моя связанная с one сущность возвращается?

Если вам нужна дополнительная информация или код, просто дайте мне знать!

Edit 1:Таблица SQL C:

dbo.TableC (
[Id] [uniqueidentifier] not null,
[Name] [string] not null)

Таблица SQL D:

dbo.TableD (
[Id] [uniqueidentifier] not null,
[TableAID] [uniqueidentifier] not null,
[TableBID] [uniqueidentifier] not null,
[TableCID] [uniqueidentifier] not null,
[ticket] [string] not null )

Таблица данных C (содержит 750 строк, сокращено до 12 для краткости): Table C data example

Таблица данных D (моя таблица ссылок вручную): Table D Example

Обновление: Диаграмма объектов для моей модели: Entity Diagram

1 Ответ

0 голосов
/ 05 марта 2019

Обновлено: Еще одно предложение

Поскольку EF Core автоматически исправит свойства навигации, вы может закончиться циклами в графе вашего объекта

Вы можете настроить Json.NET на игнорирование циклов, которые он находит в графе объектов. Это делается методом ConfigureServices(...) в Startup.cs.

public void ConfigureServices(IServiceCollection services)
{
    ...

    services.AddMvc()
        .AddJsonOptions(
            options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
        );

    ...
}

Проверка Связанные данные и сериализация

Первое предложение: убедитесь, что у вас есть новый контекст БД для текущего запроса

EF Core не поддерживает несколько параллельных операций, выполняемых на тот же экземпляр контекста

[HttpGet]
public async Task<IActionResult> GetTableDAsync()
{
    using (var_newContext = new dbContext())
    {
        var table = await _newContext.TableD
            .Include(ta => ta.TableA)
            .Include(tb => tb.TableB)
            .Include(tc => tc.TableC)
            .ToListAsync();
        return Ok(table);
    }
}

Проверьте больше о Загрузка связанных данных и Асинхронные запросы

...