Неправильное сопоставление между объектами EF приводит к неправильному ответу конечной точки.C#

Место общения программистов C#
Ответить
Anonymous
 Неправильное сопоставление между объектами EF приводит к неправильному ответу конечной точки.

Сообщение Anonymous »

В настоящее время я работаю над небольшим проектом, в котором у меня есть организация розничной торговли в системе. У каждого ритейлера есть какие-то стандарты, которые переводят его с одного уровня на другой. Каждый стандарт потребует от каждого розничного продавца действий для обеспечения соответствия, поэтому у нас есть еще две сущности: Standard, RetailerStandardCompliance. Связь между Розничным продавцом и Стандартом с соблюдением требований является связью «один ко многим», где каждому может быть присвоен список соответствия, а также список стандартов. Вот объекты:

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

public class Standard : BaseEntity
{
public string Name { get; private set; }
public string Explanation { get; private set; }
public string Criteria { get; private set; }
public string Evidence { get; private set; }
public string Level { get; private set; }
public string SectionName { get; private set; }
public string SectionNumber { get; private set; }
public decimal Weighting { get; private set; }
public IEnumerable Translations => _translations.AsEnumerable();
private readonly List _translations = new();

private Standard() { }

public Standard(string name, string explanation, string criteria, string evidence, string level, string sectionName, string sectionNumber, decimal weighting)
{
Check.For.NullOrEmpty(name);
Check.For.NullOrEmpty(explanation);
Check.For.NullOrEmpty(criteria);
Check.For.NullOrEmpty(level);
Check.For.NullOrEmpty(sectionName);
Check.For.NullOrEmpty(sectionNumber);

Name = name;
Explanation = explanation;
Criteria = criteria;
Evidence = evidence;
Level = level;
SectionName = sectionName;
SectionNumber = sectionNumber;
UpdateWeighting(weighting);
}

private void UpdateWeighting(decimal weighting)
{
Check.For.DecimalGreaterThanLimit(weighting, 100);
Check.For.DecimalLessThanOrEqualToZero(weighting);
Weighting = weighting;
}
}
А вот объект DealerStandardCompliance:

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

public class RetailerStandardCompliance : BaseEntity
{
public Guid RetailerId { get; private set; }
public Guid StandardId { get; private set; }
public Retailer Retailer { get; private set; }
public Standard Standard { get; private set; }
public bool IsPassed { get; private set; }
public string ActionToGainCompliance { get; private set; }

public RetailerStandardCompliance(bool isPassed, string actionToGainCompliance)
{
Update(actionToGainCompliance, isPassed);
}
private RetailerStandardCompliance() { }

public void Update(string actionToGainCompliance, bool isPassed)
{
Check.For.NullOrEmpty(actionToGainCompliance);
ActionToGainCompliance = actionToGainCompliance;
IsPassed = isPassed;
}
}
Функциональность, которую я хотел бы реализовать, — это создание конечной точки, которая добавляет или обновляет соответствие. Вот модель, которую пользовательский интерфейс должен будет отправить, чтобы обеспечить новое соответствие:

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

public record RetailerStandardComplianceCreateOrUpdateModel
{
public Guid? Id { get; set; }
public Guid RetailerId { get; set; }
public Guid StandardId { get; set; }
public bool IsPassed { get; set; }
public string ActionToGainCompliance { get; set; }
}
А в службе, которая выполняет создание или обновление, я сопоставляю приведенную выше модель либо с CreateModel, либо с UpdateModel, чтобы затем сопоставить ее с сущностью RetailerStandardCompliance, которая затем добавляется в базу данных. Вот модели создания и обновления:

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

public record RetailerStandardComplianceCreateModel
{
public Guid RetailerId { get; set; }
public Guid StandardId { get; set; }
public bool IsPassed { get; set; }
public string ActionToGainCompliance { get; set; }
}

public record RetailerStandardComplianceUpdateModel
{
public Guid Id { get; set; }
public Guid RetailerId { get; set; }
public Guid StandardId { get; set; }
public bool IsPassed { get; set; }
public string ActionToGainCompliance { get; set; }
}
А вот служба, которая выполняет обновление или удаление:

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

private async Task AddAsync(RetailerStandardComplianceCreateOrUpdateModel
retailerStandardComplianceCreateOrUpdateModel, CancellationToken cancellationToken)
{
var createStandardCompliance = new RetailerStandardComplianceCreateModel() with
{
RetailerId = retailerStandardComplianceCreateOrUpdateModel.RetailerId,
StandardId = retailerStandardComplianceCreateOrUpdateModel.StandardId,
ActionToGainCompliance = retailerStandardComplianceCreateOrUpdateModel.ActionToGainCompliance,
IsPassed = retailerStandardComplianceCreateOrUpdateModel.IsPassed
};
var retailerStandardCompliance = mapper.Map(createStandardCompliance);
var result = await retailerStandardComplianceRepository.AddAsync(retailerStandardCompliance, cancellationToken);

return new SuccessfulResponseModel(mapper.Map(result));
}

private async Task UpdateAsync(RetailerStandardComplianceCreateOrUpdateModel
retailerStandardComplianceCreateOrUpdateModel, CancellationToken cancellationToken)
{
var updateStandardCompliance = new RetailerStandardComplianceUpdateModel() with
{
Id = (Guid)retailerStandardComplianceCreateOrUpdateModel.Id,
RetailerId = retailerStandardComplianceCreateOrUpdateModel.RetailerId,
StandardId = retailerStandardComplianceCreateOrUpdateModel.StandardId,
ActionToGainCompliance = retailerStandardComplianceCreateOrUpdateModel.ActionToGainCompliance,
IsPassed = retailerStandardComplianceCreateOrUpdateModel.IsPassed
};
var updatedRetailerStandardCompliance = mapper.Map(updateStandardCompliance);
var result = await retailerStandardComplianceRepository.UpdateAsync(updatedRetailerStandardCompliance, cancellationToken);

return new SuccessfulResponseModel(mapper.Map(result));
}
И, наконец, вот как я делаю сопоставление с помощью automapper, чтобы получить результат:

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

public class RetailerStandardComplianceProfile : Profile
{
public RetailerStandardComplianceProfile()
{
CreateMap()
.IncludeMembers(rst => rst.Retailer, rst => rst.Standard);

CreateMap(MemberList.Source);

CreateMap(MemberList.Source);

CreateMap()
.ForMember(src => src.StandardId, opt => opt.MapFrom(dest => dest.Id))
.ForSourceMember(src => src.Explanation, opt => opt.DoNotValidate())
.ForSourceMember(src => src.Criteria, opt => opt.DoNotValidate())
.ForSourceMember(src => src.Evidence, opt => opt.DoNotValidate())
.ForSourceMember(src => src.Level, opt => opt.DoNotValidate())
.ForSourceMember(src => src.SectionName, opt => opt.DoNotValidate())
.ForSourceMember(src => src.SectionNumber, opt => opt.DoNotValidate());

CreateMap()
.ForMember(src => src.RetailerId, opt => opt.MapFrom(dest =>  dest.Id));
}
}
И обратный профиль:

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

public class RetailerStandardComplianceReverseProfile : Profile
{
public RetailerStandardComplianceReverseProfile()
{
CreateMap()
.ConvertUsing((src, dest, _) =>
{
if (dest is null)
{
var retailerStandardCompliance = new RetailerStandardCompliance(src.IsPassed, src.ActionToGainCompliance);
return retailerStandardCompliance;
}
dest.Update(src.ActionToGainCompliance, src.IsPassed);
return dest;
});

CreateMap();

CreateMap()
.ForMember(dest => dest.RetailerId, opt => opt.MapFrom(src => src.RetailerId))
.ForMember(dest => dest.StandardId, opt => opt.MapFrom(src => src.StandardId))
.ForMember(dest => dest.Retailer, opt => opt.Ignore())
.ForMember(dest => dest.Standard, opt => opt.Ignore())
.ConstructUsing(src => new RetailerStandardCompliance(src.IsPassed, src.ActionToGainCompliance));

CreateMap(MemberList.Source);

}
}
Проблема заключается в том, что когда я пытаюсь использовать метод post для добавления нового соответствия, он не заполняет RetailerId или StandardId, Standard или Retailer и говорит, что идентификатор Продавец, которого я указал, не существует и не соответствует продавцу в системе.
P.S. Вот конфигурация RetailerStandardCompliance в базе данных:

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

public class RetailerStandardComplianceConfiguration : IEntityTypeConfiguration
{
public void Configure(EntityTypeBuilder builder)
{
builder.HasKey(rsc => rsc.Id);

builder.HasOne(rsc => rsc.Retailer)
.WithMany()
.HasForeignKey(rsc => rsc.RetailerId);

builder.HasOne(rsc => rsc.Standard)
.WithMany()
.HasForeignKey(rsc => rsc.StandardId);

builder.Property(rsc => rsc.IsPassed)
.IsRequired();

builder.Property(rsc => rsc.ActionToGainCompliance)
.IsRequired()
.HasMaxLength(2000);
}
}
Я буду благодарен, если кто-нибудь сможет проверить, правильно ли выполнены сопоставления, поскольку мне потребовалось два дня, чтобы это понять.
Спасибо< /п>

Подробнее здесь: https://stackoverflow.com/questions/788 ... e-of-the-e
Ответить

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

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

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

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

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