Как избежать свойств круговой навигации в Entity Framework Core? - PullRequest
1 голос
/ 20 сентября 2019

У меня есть такая схема таблицы:

CREATE TABLE Categories
(
    Id INT IDENTITY(1,1),
    Name varchar(100),
    CONSTRAINT PK_Category_Id PRIMARY KEY (Id)
)

CREATE TABLE Products
(
    Id INT IDENTITY(1,1),
    IdCategory INT NOT NULL
        CONSTRAINT FK_Products_IdCategory__Categories_Id FOREIGN KEY(IdCategory) REFERENCES Categories(Id),
    Name varchar(100), 
    Price decimal(18,2),
    ImageUrl varchar(256),
    CONSTRAINT PK_Product_Id PRIMARY KEY (Id)
)

EF Core сгенерировал следующий код:

public partial class Categories
{
    public Categories()
    {
        Products = new HashSet<Products>();
    }

    public int Id { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Products> Products { get; set; }
}

public partial class Products
{
    public Products()
    {
        OrderItems = new HashSet<OrderItems>();
        ShoppingCartItems = new HashSet<ShoppingCartItems>();
    }

    public int Id { get; set; }
    public int IdCategory { get; set; }
    public string Name { get; set; }
    public decimal? Price { get; set; }
    public string ImageUrl { get; set; }

    public virtual Categories IdCategoryNavigation { get; set; }
    public virtual ICollection<Items> Items { get; set; }        
}

И OnModelCreating(ModelBuilder modelBuilder) Метод:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasAnnotation("ProductVersion", "2.2.6-servicing-10079");

    modelBuilder.Entity<Categories>(entity =>
    {
        entity.Property(e => e.Name)
            .HasMaxLength(100)
            .IsUnicode(false);
    });

    modelBuilder.Entity<Products>(entity =>
    {
        entity.Property(e => e.ImageUrl)
            .HasMaxLength(256)
            .IsUnicode(false);

        entity.Property(e => e.Name)
            .HasMaxLength(100)
            .IsUnicode(false);

        entity.Property(e => e.Price).HasColumnType("decimal(18, 2)");

        entity.HasOne(d => d.IdCategoryNavigation)
            .WithMany(p => p.Products)
            .HasForeignKey(d => d.IdCategory)
            .OnDelete(DeleteBehavior.ClientSetNull)
            .HasConstraintName("FK_Products_IdCategory__Categories_Id");
    });
}

Я написал следующий код:

public override async Task<Products> GetById(int id)
{   
    return await DbContext.Products
        .Include(p => p.IdCategoryNavigation)
        .FirstOrDefaultAsync(p => p.Id == id);
}

И у меня есть следующие свойства круговой навигации, и эти свойства будут создаваться, пока я не нажму Products: enter image description here

Как можно избежать свойств круговой навигации?Пожалуйста, скажите мне, что я сделал не так?Это ожидаемое и правильное поведение?

1 Ответ

2 голосов
/ 21 сентября 2019

Это ожидаемая часть любого языка программирования, потому что всегда можно создавать объекты, которые ссылаются друг на друга.При визуализации этого отладчик В visual studio просто отображает ссылки в том виде, в каком он их видит, в ответ на вашу навигацию по дереву объектов

Отойдя на мгновение от Entity Framework, рассмотрим универсальный класс коллекции LinkedList, которыйсцепленная коллекция объектов LinkedListNode.У каждого узла есть Next и Previous, в то время как сам список имеет First и Last (следовательно, связь является двунаправленной)

Если вы поместите два элемента в свой список, «hello» и «world», тогда изучитев отладчике вы увидите:

list.First          LinkedListNode "hello"
  .Next             LinkedListNode "world"
    .Previous       LinkedListNode "hello"
      .Next         LinkedListNode "world"

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

list.First.Next.Previous.Next; //"world

Вы также можете чередовать набор Next и Previous весь день - это допустимо в C #, хотя, вероятно, и не нужно, если вы не гуляетедерево, которое ветвится, и вы хотите подняться ближе к корню, прежде чем идти по другой ветке

Эта «циклическая» структура появляется везде, где объект ссылается на другой объект, который ссылается на оригинал - DataRows DataTableу каждого есть свойство .Table, которое ссылается на таблицу, которой принадлежит строка, и так далее.Не проблема и не приведет к поломке вашего кода в каком-то бесконечном цикле - EF не будет пытаться спасти Клиентов, затем Заказы Клиента, затем Заказы Клиентов, а затем Заказы Клиентов.и т. д. Он знает, когда прекратить сохранение пары заказов клиентов

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