Не удается получить доступ к свойствам навигации при проецировании в конструкторе - PullRequest
0 голосов
/ 26 апреля 2019

Я пытаюсь преобразовать свою базу данных из DbSet в контекстную модель. Моя база данных в настоящее время использует отложенную загрузку для загрузки свойств навигации. Я могу достичь этого, просто набрав .Where(d => new ContextClass { Prop1 = d.Prop1, Prop2 = d.Prop2.Prop }). Но скажем теперь, что ContextClass имеет конструктор, который принимает d, и я выполняю инициализацию свойства там, я больше не могу получить доступ к свойствам навигации и получить проблему с отложенной загрузкой.

Мои объекты:

public class Entity1
{
  public string Prop1 { get; set; }
  public virtual Entity2 Prop2 { get; set; }
}

public class Entity2
{
  public string Prop { get; set; }
}

public class ContextClass
{
  public string Prop1 { get; set; }
  public string Prop2 { get; set; }

  public ContextClass()
  {
  }

  public ContextClass(Entity1 entity)
  {
    Prop1 = entity.Prop1;
    Prop2 = entity.Prop2.Prop;
  }
}

Рабочий запрос:

  .Select(e => new ContextClass
  {
    Prop1 = e.Prop1,
    Prop2 = e.Prop2.Prop
  })
  .ToListAsync();

нерабочий запрос:

  .Select(e => new ContextClass(e))
  .ToListAsync();

Это ошибка, которую я получаю:

Error generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.DetachedLazyLoadingWarning: An attempt was made to lazy-load navigation property 'Entity2' on detached entity of type 'Entity1Proxy'. Lazy-loading is not supported for detached entities or entities that are loaded with 'AsNoTracking()'.'. This exception can be suppressed or logged by passing event ID 'CoreEventId.DetachedLazyLoadingWarning' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'.

1 Ответ

0 голосов
/ 26 апреля 2019

Мне удалось решить эту проблему, используя метод расширения для выполнения обычного оператора выбора LINQ to SQL вместо инициализации конструктора.

public static IQueryable<ContextClass> SelectAsContext(this IQueryable<Entity1> queryable)
{
  return queryable.Select(x => new ContextClass
  {
    Prop1 = x.Prop1,
    Prop2 = x.Prop2.Prop
  });
}

Так в коде вызова:

var contexts = await queryable.SelectAsContext().ToListAsync();

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

...