InsertOrUpdate> Insert OK, обновление не работает - PullRequest
0 голосов
/ 09 мая 2020

Несколько дней назад go Я попробовал AutMapper с Entity Framework Core, теперь я хочу посмотреть, как работает InsertOrUpdate from AutoMapper.Collection.EntityFrameworkCore (v1.0.1). Но я не могу запустить его в работу, вот мои тестовые классы / настройки:

DataContext (DbContext)

public class DataContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseLazyLoadingProxies(false).EnableSensitiveDataLogging(AppHelper.ShowDebugInfos).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking).UseSqlServer(AppHelper.ConnectionString);
    }

    public DbSet<Contact> Contacts { get; set; } // with some references to other tables
}

Startup

services.AddDbContext<DataContext>();

services.AddEntityFrameworkInMemoryDatabase().AddDbContext<DataContext>(); // not sure if we need this for InsertOrUpdate

services.AddAutoMapper(automapper =>
{
    automapper.AddCollectionMappers();
    automapper.UseEntityFrameworkCoreModel<DataContext>(services);
    //automapper.SetGeneratePropertyMaps<GenerateEntityFrameworkCorePrimaryKeyPropertyMaps<DataContext>>(); // exception says we have to use UseEntityFrameworkCoreModel instead of this
}, typeof(DataContext).Assembly);

AutoMapperProfile

public class AutoMapperProfile : Profile
{
    CreateMap<ContactTestDto, Contact>().ReverseMap();

    // did also try:
    //CreateMap<ContactTestDto, Contact>().EqualityComparison((source, destination) => source.Id == destination.Id);
    //CreateMap<Contact, ContactTestDto>().EqualityComparison((source, destination) => source.Id == destination.Id);
}

Контактная информация модели

public partial class Contact
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    // many more (including navigation properties)...
}

Модель ContactTestDto

public partial class ContactTestDto
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    // nothing more
}

Обновление

// this makes no difference:
//Contact contactFromDb = db.Contacts.Find(1); // FirstName is "John"
//db.Entry(contactFromDb).State = EntityState.Modified;

// nothing happens:
db.Contacts.Persist(mapper).InsertOrUpdate(new ContactTestDto { Id = 1, FirstName = "Updated Name???" });

// insert ok:
db.Contacts.Persist(mapper).InsertOrUpdate(new ContactTestDto { FirstName = "Inserted Name" });

db.SaveChanges();

Я вижу Select-Statements it оба случаев (через SQL Profiler ), но при обновлении обновлений нет, вставка в порядке. Также экземпляр mapper работает нормально (я могу отображать в обоих направлениях).

Итак, что я сделал не так?

PS: Почему я не могу написать «Hello SO-Community "? Сократится до "Сообщества" oO

1 Ответ

1 голос
/ 10 мая 2020

Вы отключили отслеживание в параметрах базы данных (.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)), поэтому вам нужно либо включить его обратно с помощью параметров, либо включить его для таких запросов, как это:

var currTracking = db.ChangeTracker.QueryTrackingBehavior;
try
{
    db.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.TrackAll;
    db.Contacts
        .Persist(mapper)
        .InsertOrUpdate(new ContactDto { Id = 1, FirstName = "Updated Name???" });
    db.Contacts.Persist(mapper).InsertOrUpdate(new ContactDto { FirstName = "Inserted Name" });
    db.SaveChanges();
}
finally
{
    db.ChangeTracker.QueryTrackingBehavior = currTracking;
}

PS не уверен, что настройка обратно to currTracking требуется через try-finally, но лучше перестраховаться.

...