Невозможно явно загрузить свойства навигации с помощью лямбда-выражения

#c# #.net-core #entity-framework-core

#c# #.net-core #entity-framework-core

Вопрос:

Я обновляю проект .NET Core 2.2 до .NET Core 3.1 с помощью Entity Framework Core. У меня возникли некоторые проблемы при попытке использовать явную загрузку свойств навигации. Я могу передать строку в методы .Collection() or .Reference() , но все, что я вижу для явной загрузки, использует лямбда-выражения. Я не смог найти пакет, который предоставил бы мне лямбда-версию этого метода.

Код, который создает:

 var item = _dbContext.Users.First();
var entry = _dbContext.Entry(item).Collection("Address");
 

Код, который не будет построен:

 var item = _dbContext.Users.First();
var entry = _dbContext.Entry(item).Collection(x => x.Address);
 

Сообщение в VS Code для кода, который не будет построен

Невозможно преобразовать лямбда-выражение в тип ‘string’, поскольку оно не является типом делегата [RH.Api] csharp(CS1660)

Пользовательская модель

 public class User
{
    public Guid UserId { get; set; }
    public Guid AddressId { get; set; }
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
    public string Suffix { get; set; }
    public string Email { get; set; }
    public UserStatus? Status { get; set; }
    public DateTime CreatedDate { get; set; }
    public Guid CreatedBy { get; set; }
    public DateTime? LastModifiedDate { get; set; }
    public Guid? LastModifiedBy { get; set; }

    [ForeignKey("AddressId")]
    public Address Address { get; set; }
}
 

Адресная модель

 public class Address
{
    public Guid AddressId { get; set; }
    public string AddressLine1 { get; set; }
    public string AddressLine2 { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string Zip { get; set; }
    public string County { get; set; }
    public DateTime CreatedDate { get; set; }
    public Guid CreatedBy { get; set; }
    public DateTime? LastModifiedDate { get; set; }
    public Guid? LastModifiedBy { get; set; }
}
 

Комментарии:

1. Какое сообщение об ошибке вы получили? Можете ли вы показать нам свою модель?

2. @mj1313 Обновил описание, включив информацию

Ответ №1:

Address не является типом коллекции, изменяя ваш код на

 var entry = _dbContext
    .Entry(item)
    .Reference(x => x.Address)
    .Load();
 

Чтобы понять смысл сообщения об ошибке ( Cannot convert lambda expression to type 'string' because it is not a delegate type [RH.Api] csharp(CS1660) ), взгляните на сигнатуру Collection метода перегрузки метода:

  • Collection<TProperty>(Expression<Func<TEntity,IEnumerable<TProperty>>>)
  • Collection(String)

Выражение x => x.Address не возвращает an IEnumerable<T> , поэтому компилятор пытается преобразовать выражение в string и терпит неудачу.

Комментарии:

1. Это не было проблемой, я не получил параметр lambda с .Reference() или с .Collection()

Ответ №2:

Я нашел проблему. Мое решение используется не DbContext напрямую, а через наследование и интерфейс. So Entry() был переопределен, и я не уловил, что он возвращался только EntityEntry вместо EntityEntry<TEntity> . Изменение переопределения устранило мою проблему.

Старый:

 public interface IDbContext : IDisposable
{
    EntityEntry Entry(object entity);
}

public class MyDbContext: DbContext, IDbContext
{
    public override EntityEntry Entry(object entity)
    {
        return base.Entry(entity);
    }
}
 

Новое:

 public interface IDbContext : IDisposable
{
    EntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class;
}

public class MyDbContext: DbContext, IDbContext
{
    public override EntityEntry<TEntity> Entry<TEntity>(TEntity entity) where TEntity : class
    {
        return base.Entry(entity);
    }
}