EF Core загружает отношения, когда я этого не хочу - PullRequest
1 голос
/ 10 октября 2019

У меня есть служба, которая возвращает объекты, используя EagerLoading . По большей части это работает, но я недавно нашел проблему. У меня есть поле:

public class Field
{
    [Required] public int Id { get; set; }
    [Required, MaxLength(100)] public string CategoryId { get; set; }
    [Required, MaxLength(100)] public string Name { get; set; }
    public FieldDataType DataType { get; set; }
    public bool IsSpecification { get; set; }

    public IList<FieldMap> FieldMaps { get; set; }
}

Как видите, с ним связана коллекция FieldMaps . FieldMap выглядит следующим образом:

public class FieldMap
{
    public int Id { get; set; }
    public int FeedId { get; set; }
    public int FieldId { get; set; }
    [Required, MaxLength(100)] public string Path { get; set; }

    public Field Field { get; set; }
}

, который отображается в моем DbContext следующим образом:

modelBuilder.Entity<Field>().HasMany(m => m.FieldMaps).WithOne().HasForeignKey(m => m.FieldId);

// Unique constraints
modelBuilder.Entity<Field>().HasIndex(m => new { m.CategoryId, m.Name, m.IsSpecification }).IsUnique();
modelBuilder.Entity<FieldMap>().HasIndex(m => new { m.FeedId, m.Path }).IsUnique();

// Disable cascade delete
modelBuilder.Entity<FieldMap>().HasOne(m => m.Field).WithMany(m => m.FieldMaps).OnDelete(DeleteBehavior.Restrict);

Проблема в том, что когда я вызываю List метод, он возвращает все элементы навсегда:

enter image description here

Мой метод списка выглядит так:

public IQueryable<T> List(params string[] includes)
{
    IQueryable<T> query = _dbEntitySet;

    return includes == null ? 
        query : 
        includes.Aggregate(query, (current, include) => current.Include(include));
}

И я вызываю его так:

[HttpGet("{id:int}/fields")]
[ProducesResponseType(typeof(List<Field>), StatusCodes.Status200OK)]
public IActionResult ListFieldMaps(int id)
{
    var feeds = _feedService.List();
    var feed = feeds.SingleOrDefault(m => m.Id.Equals(id));
    if (feed == null) return NotFound();

    var fieldMaps = _fieldMapService.List("Field");

    if (fieldMaps.Any(m => m.Field == null)) return BadRequest(Resources.NullFieldError);

    return Ok(fieldMaps.Where(m =>
        m.FeedId.Equals(id) &&
        m.Field.IsSpecification == (feed.Type == FeedType.Specification)).ToList());
}

Как видите, он должен загружать только список FieldMaps с одним полем , а не с остальнымикарты полей после этого.

Может кто-нибудь помочь мне с этой проблемой?

Ответы [ 2 ]

1 голос
/ 10 октября 2019

Я нашел эту статью:

https://docs.microsoft.com/en-us/ef/core/querying/related-data#lazy-loading

и эту проблему:

https://github.com/aspnet/EntityFrameworkCore/issues/11564

и от них обоих удалосьдобавьте это:

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

Что привело к решению моей проблемы. Теперь, когда я делаю запрос, я получаю этот ответ:

[
    {
        "Id": 1,
        "FeedId": 1,
        "FieldId": 10,
        "Path": "aw_product_id",
        "Field": {
            "Id": 10,
            "CategoryId": "cameras",
            "Name": "gtin",
            "DataType": 0,
            "IsSpecification": false,
            "FieldMaps": []
        }
    }
]
1 голос
/ 10 октября 2019

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

Из документации :

Entity Framework Core автоматически исправит свойства навигации для любых других объектов, которые ранее были загружены в экземпляр контекста. Поэтому, даже если вы явно не включаете данные для свойства навигации, свойство все равно может быть заполнено, если ранее были загружены некоторые или все связанные объекты.

Попробуйте установить Object Id в Visual Studio(добавьте переменную в Watch, щелкните правой кнопкой мыши по ней и выберите «Make Object ID»). Это создаст уникальный идентификатор для каждого экземпляра и сообщит вам, загружаете ли вы разные объекты.

...