Запрос списка в неотслеживаемой модели, отслеживающий элементы списка - PullRequest
0 голосов
/ 27 апреля 2018

Я получаю сообщение об ошибке

Не удалось подключить объект типа «Application.Models.DatabaseModels.Bar», поскольку другой объект того же типа уже имеет такое же значение первичного ключа.

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

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

Это прекрасно работает:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(ViewModel viewModel)
{
    Foo foo = await _context.Foos.AsNoTracking().FirstOrDefaultAsync(f => f.Id == viewModel.FooId);
    Foo.Primary.Bar = _context.Bars.AsNoTracking().First(c => c.Id == viewModel.PrimaryBarId);

    _context.SetModified(foo.Primary);

    //code continues
}

Это выдает ошибку:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(ViewModel viewModel)
{
    Foo foo = await _context.Foos.AsNoTracking().FirstOrDefaultAsync(f => f.Id == viewModel.FooId);
    Foo.Primary.Bar = _context.Bars.AsNoTracking().First(c => c.Id == viewModel.PrimaryBarId);

    //this appears to add the Bars in Foo to the context
    var test = foo.Bars.Where(c => c.Id != foo.Primary.Bar.Id);

    //this is where the error occurs now
    _context.SetModified(foo.Primary);

    //code continues
}

Чтобы дать контекст ситуации:

Модели баз данных

public class Foo
{
    public int Id { get; set; }

    [ForeignKey("Primary")]
    public int? PrimaryId { get; set; }
    public virtual Primary Primary { get; set; }

    public virtual List<Bar> Bars { get; set; }
}

public class Bar
{
    public int Id { get; set; }

    [ForeignKey("Foo")]
    public int? FooId { get; set; }
    public virtual Foo Foo { get; set; }
}

public class Primary
{
    [Key, ForeignKey("Foo")]
    public int FooId { get; set; }
    public virtual Foo Foo { get; set; }

    [ForeignKey("Bar")]
    public int? BarId { get; set; }
    public virtual Bar Bar { get; set; }
}

Просмотр модели

public class ViewModel
{
    public int FooId { get; set; }
    public int? PrimaryBarId { get; set; }
}

Context

public class AppDbContext : DbContext
{
    public virtual DbSet<Foo>           Foos            { get; set; }
    public virtual DbSet<Bar>           Bars            { get; set; }
    public virtual DbSet<Primary>       PrimaryBars     { get; set; }


    public virtual void SetModified<T>(T entity) where T : class
    {
        Entry(entity).State = EntityState.Modified;
    }
}

Вопрос

Почему строка var test = foo.Bars.Where(c => c.Id != foo.Primary.Bar.Id); вызывает отслеживание Bar контекста, даже если для foo установлено значение AsNoTracking()?

Я неправильно понимаю, что здесь происходит, что делает AsNoTracking(), или это ошибка в самой Entity Framework?

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