Пример: < /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; }
}
Код: Выделить всё
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();
});
Код: Выделить всё
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
Чего мне не хватает? У меня много кода, использующего этот шаблон, так как он работал просто великолепно, теперь я не могу заставить его работать, не написав кучу включения и использования 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>
работает. Таким образом, на мой взгляд, код, который у меня был ранее, должен был сработать, и не должен был конвертировать его в использование выбора с проекцией для чтения связанных объектов. Все это работало в EF7, и со всеми вещами, которые я нахожу в Efcore 8, которые больше не работают, я собираюсь взять руки на преобразование этого проекта.
Подробнее здесь: https://stackoverflow.com/questions/796 ... o-database