Имеет проблемы с получением EF Core 8 Lazy Lazy Roading после обновления в базу данныхC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Имеет проблемы с получением EF Core 8 Lazy Lazy Roading после обновления в базу данных

Сообщение Anonymous »

Во -первых, позвольте мне начать с того, что я пытаюсь преобразовать большой проект ASP.Net Web API из .NET 4.8, EF 6 в .NET 8 и EF CORE 8. При этом я заметил, что большая часть кода приложения работает хорошо после переноса. Мы используем ленивые прокси нагрузки из -за того, что в большинстве ситуаций я должен получить доступ к большей части данных во многих местах и ​​станет кошмаром для кодирования всех включенных, чтобы получить данные. Я обнаружил, что, как только я выполняю обновление в базе данных, многие из связанных объектов не будут ленивы загружать соответствующие данные таблицы, когда я попытаюсь получить доступ к этим свойствам. Это особенно выяснилось, когда у вас может быть промежуточная таблица, чтобы удерживать отношения между 2 объектами. < /P>
Пример: < /p>

Код: Выделить всё

public partial class Name
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int NameID { get; set; }

public virtual ICollection NameLocations { get; set; }
}

public partial class Location
{
public int LocationID { get; set; }
public virtual ICollection NameLocations { get; set; }
}

public partial class NameLocation
{
public int NameLocationID { get; set; }
public int NameID { get; set; }
public int LocationID { get; set; }

public DateTime CreationDate { get; set; }
public DateTime LastModifiedDate { get; set; }

public virtual Location Location { get; set; }
public virtual Name Name { get; set; }
}
В программе я настраиваю dbcontext Например:

Код: Выделить всё

var connString = builder.Configuration.GetConnectionString("Context");
builder.Services.AddEntityFrameworkSqlServerNetTopologySuite();
builder.Services.AddEntityFrameworkSqlServer()
.AddEntityFrameworkProxies()
.AddDbContext((serviceProvider, options) =>
{
options.UseSqlServer(connString, sqlServerOptionsAction: sqlOptions =>
{
sqlOptions.EnableRetryOnFailure();
sqlOptions.UseNetTopologySuite();
}).UseInternalServiceProvider(serviceProvider);
options.UseLazyLoadingProxies();
});
и в dbcontext объекты определяются так:

Код: Выделить всё

modelBuilder.Entity(entity => {
{
entity.HasMany(e => e.NameLocations)
.WithOne(e => e.Location)
.HasForeignKey(e => e.LocationID)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_NameLocation_Location");
});

modelBuilder.Entity(entity => {
entity.HasMany(e => e.NameLocations)
.WithOne(e => e.Name)
.HasForeignKey(e => e.NameID)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_NameLocation_Name");
});
< /code>
Я добавляю новый объект местоположения имени на график, настраивающий правильный идентификатор идентификатора идентификатора идентификатора идентификатора идентификатора, а затем добавляя в контекст и вызовет изменения сохранения. Затем я прочитал данные обратно, используя findasync 
, используя вновь созданный идентификатор объекта. Все это работало нормально в EF Core 7, но я почесываю голову на то, как заставить его работать над EF Core 8. < /p>
Чего мне не хватает? У меня много кода, использующего этот шаблон, так как он работал просто великолепно, теперь я не могу заставить его работать, не написав кучу включения и использования Firstordefault () .
У меня есть модель намелокации, которая является объектом DTO, которая очень похожа на сущность, но имеет другие свойства, которые можно отображать на экране, которые будут отображаться на экране. />public async Task UpsertDistributionAsync(NameLocationModel model)
{
var rt = new NameLocationModel();
NameLocation entity = null;
if (model.NameLocationId > 0)
entity = await _context.NameLocations.FindAsync(model.NameLocationId);

entity = model.ToEntity(entity, _context);
if (entity.NameLocationID < 1)
{

_context.NameLocations.Add(entity);
}

if ((_context.ChangeTracker.HasChanges()))
{
await _context.SaveChangesAsync();
}

entity = await _context.NameLocations.FindAsync(entity.NameLocationID)
rt.Model = entity.ToModel();
}
< /code>
И это конвертер модели, где соответствующие объекты являются нулевыми. Как вы можете видеть, здесь много кода, поэтому стараюсь не выпускать все это. < /p>
public static class NameLocationModelConverter
{
public static NameLocationModel ToModel(this NameLocation entity) {
if (entity == null)
return null;

var model = new NameLocationModel
{
NameLocationId = entity.NameLocationID,
ReferenceId = entity.ReferenceID,
NameId = entity.NameID,
ContinentId = entity.Location.GetContinentId(),
CountryId = entity.Location.GetCountryId(),
UpperId = entity.Location.GetUpperId(),
LowerId = entity.Location.GetLowerId(),
LocationId = entity.LocationID,
ContinentName = entity.Location.GetContinentName(),
CountryName = entity.Location.GetCountryName(),
CreationDate = entity.CreationDate,
LowerName = entity.Location.GetLowerName(),
UpperName = entity.Location.GetUpperName(),
ArticleTitle = string.IsNullOrWhiteSpace(entity.Reference.ArticleTitle) ? "(none)" : entity.Reference.ArticleTitle.ReplacePickHtml(),
Collation = entity.Reference.ArticleCollation,
YearPublished = entity.Reference.YearPublished,
TitlePageYear = entity.Reference.TitlePageYear,
AuthorString = entity.Reference.AuthorString,
LastModifiedDate = entity.LastModifiedDate,
Publication = entity.Reference.Title?.AbbreviatedTitle,
LocationDisplayString = entity.Location.FormatLocationName(),
TitleId = entity.Reference?.TitleID,
FamilyName = entity.Name.Rank.RankPositionID > (int)RankPositions.Family ? entity.Name?.FamilyName?.FullName ?? "Unknown" : "",
FamilyNameId = entity.Name.FamilyNameID,
ScientificName = NameFunctions.DisplayName(entity.Name.FullName, null, NameFunctions.FormatAuthorString(entity.Name.AuthorString, entity.Name.BasionymName?.AuthorString, entity.Name.Rank.RankPositionID), entity.Name.IsFossil)
};

return model;
}

public static NameLocation ToEntity(this NameLocationModel model, NameLocation entity, TropicosContext context)
{
if (model == null)
return entity;

var rt = entity;
if (entity == null) {
rt = new NameLocation
{
NameLocationID = 0,
CreationDate = DateTime.Now
};
}

rt.NameID = model.NameId;
rt.LocationID = model.LocationId;
rt.ReferenceID = model.ReferenceId;

if (rt.NameLocationID == 0 || context.ChangeTracker.Entries().Any(e => e.State == EntityState.Modified && e.Entity.NameLocationID == rt.NameLocationID))
rt.LastModifiedDate = DateTime.Now;

return rt;
}

}
< /code>
Я понимаю, что попытка репроектировать проблему важна, но публикация всего кода может занять много места. Теперь я узнал, что замена кода Tomodel () в моей конвертере на эту функцию, которая, как вы можете видеть, представляет собой тот же код, что и функция Tomodel (): < /p>
public static Expression ProjectToModel {
get {
return entity => new NameLocationModel {
NameLocationId = entity.NameLocationID,
ReferenceId = entity.ReferenceID,
NameId = entity.NameID,
ContinentId = entity.Location.GetContinentId(),
CountryId = entity.Location.GetCountryId(),
UpperId = entity.Location.GetUpperId(),
LowerId = entity.Location.GetLowerId(),
LocationId = entity.LocationID,
ContinentName = entity.Location.GetContinentName(),
CountryName = entity.Location.GetCountryName(),
CreationDate = entity.CreationDate,
LowerName = entity.Location.GetLowerName(),
UpperName = entity.Location.GetUpperName(),
ArticleTitle = string.IsNullOrWhiteSpace(entity.Reference.ArticleTitle) ? "(none)" : entity.Reference.ArticleTitle.ReplacePickHtml(),
Collation = entity.Reference.ArticleCollation,
YearPublished = entity.Reference.YearPublished,
TitlePageYear = entity.Reference.TitlePageYear,
AuthorString = entity.Reference.AuthorString,
LastModifiedDate = entity.LastModifiedDate,
Publication = entity.Reference.TitleID.HasValue ? entity.Reference.Title.AbbreviatedTitle: "",
LocationDisplayString = entity.Location.FormatLocationName(),
TitleId = entity.Reference.TitleID,
FamilyName = entity.Name.Rank.RankPositionID > (int)RankPositions.Family && entity.Name.FamilyNameID.HasValue ? entity.Name.FamilyName.FullName ?? "Unknown" : "",
FamilyNameId = entity.Name.FamilyNameID,
ScientificName = NameFunctions.DisplayName(entity.Name.FullName, null, NameFunctions.FormatAuthorString(entity.Name.AuthorString, entity.Name.BasionymNameID.HasValue ? entity.Name.BasionymName.AuthorString : null, entity.Name.Rank.RankPositionID), entity.Name.IsFossil)
};
}
}
< /code>
и замена строки в службе, чтобы назвать ее таким образом после изменений сохранения: < /p>
rt.Model = await _context.NameLocations.Where(nl => nl.NameLocationID == entity.NameLocationID).Select(NameLocationModelConverter.ProjectToModel).FirstOrDefaultAsync();
< /code>
работает. Таким образом, на мой взгляд, код, который у меня был ранее, должен был сработать, и не должен был конвертировать его в использование выбора с проекцией для чтения связанных объектов. Все это работало в EF6, и со всеми вещами, которые я нахожу в Efcore 8, которые больше не работают, я собираюсь взять руки на преобразование этого проекта.

Подробнее здесь: https://stackoverflow.com/questions/796 ... o-database
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»