#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);
}
}