微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

asp.net 样板错误地将实体保存为已删除

如何解决asp.net 样板错误地将实体保存为已删除

这是我在这里的第一篇文章,如果我没有提供足够的信息,请见谅。

我们将 ABP v5.1 与 sql Server 数据库一起使用。我们有一个 Message 实体,它继承自 FullAuditedEntity<int>,具有用于消息状态、类型和关联公司的各种 ID。

获取与状态和类型 id 关联的值,我们从数据库中的表中查找,该表具有 Id、Group 和 Title 列。

消息的 CRUD 操作类是 MessageAppService,它继承自 AsyncCrudAppService,并具有用于创建和更新的覆盖,在使用查找值进行一些输入操作后,它也调用覆盖的基方法。>

问题是,当我提交对调用 MessageAppService.UpdateAsync 的消息的更新时,它会将 IsDeleted 布尔值设置为 true,而在输入中它为 false。只有当我尝试从数据库中查找时才会发生这种情况。注释掉代码以获得预期的行为结果。

我将 AsyncCrudAppService.UpdateAsync代码复制到我的代码中,以查看它将 IsDeleted 更改为 false 的位置,并在 await CurrentUnitOfWork.SaveChangesAsync() 调用中更改它。

如果邮件明显不应该被删除,我该如何阻止它标记为已删除

相关代码如下:

消息应用服务

public class MessageAppService : AsyncCrudAppService<Message,MessageDto,int,PagedMessageResultRequestDto,CreateUpdateMessageDto,CreateUpdateMessageDto>,IMessageAppService
    {
        private readonly IRepository<Message> _messageRepository;
        private readonly MessageGroupAppService _messageGroupAppService;
        private readonly RecipientGroupAppService _recipientGroupAppService;
        private readonly MessageRecipientAppService _messageRecipientAppService;
        private readonly RecipientAppService _recipientAppService;
        private readonly RoleManager _roleManager;
        private readonly UserManager _userManager;
        private readonly INotificationPublisher _notificationPublisher;
        private readonly IConfiguration _configuration;
        private readonly LookUpAppService _lookUpAppService;

        public MessageAppService(IRepository<Message> messageRepository,MessageGroupAppService messageGroupAppService,RecipientGroupAppService recipientGroupAppService,MessageRecipientAppService messageRecipientAppService,RecipientAppService recipientAppService,RoleManager roleManager,UserManager userManager,INotificationPublisher notificationPublisher,IConfiguration configuration,LookUpAppService lookUpAppService)
            : base(messageRepository)
        {
            _messageRepository = messageRepository;
            _messageGroupAppService = messageGroupAppService;
            _recipientGroupAppService = recipientGroupAppService;
            _messageRecipientAppService = messageRecipientAppService;
            _recipientAppService = recipientAppService;
            _roleManager = roleManager;
            _userManager = userManager;
            _notificationPublisher = notificationPublisher;
            _configuration = configuration;
            _lookUpAppService = lookUpAppService;
        }

        public override async Task<MessageDto> CreateAsync(CreateUpdateMessageDto input)
        {
            return await ProcessMessage(input,true);
        }

        public override async Task<MessageDto> UpdateAsync(CreateUpdateMessageDto input)
        {
            return await ProcessMessage(input,false);
        }

        private async Task<MessageDto> ProcessMessage(CreateUpdateMessageDto input,bool create)
        {
            // Calling this causes `base.UpdateAsync` to set `IsDeleted` to `true`
            var messageState = (await _lookUpAppService.GetLookup("MessageState",input.StateLookUpId)).Title;

            var emailApprovers = false;
            var sendMessage = false;

            switch (messageState)
            {
                case "Pending":
                    // Calling this causes `base.UpdateAsync` to set `IsDeleted` to `true`
                    var company = (await _lookUpAppService.GetLookup("Company",input.CompanyLookUpId)).Title;

                    var permissionName = $"{company.toupper()}.Message.Approve";

                    if (!await PermissionChecker.IsGrantedAsync(permissionName))
                    {
                        emailApprovers = true;
                    }

                    break;
                case "Approved":
                    input.ApprovingUserId = AbpSession.UserId.Value;
                    sendMessage = true;
                    break;
            }

            MessageDto message;
            if (create)
            {
                message = await base.CreateAsync(input);
            }
            else
            {
                // `AsyncCrudAppService.UpdateAsync(input)` code from ABP git repo
                CheckUpdatePermission();

                var entity = await GetEntityByIdAsync(input.Id);

                MapToEntity(input,entity);

                // `entity` has correct values before this line
                await CurrentUnitOfWork.SaveChangesAsync();
                // `entity` is Now soft deleted

                message = MapToEntityDto(entity);
            }

            if (input.GroupIds != null)
            {
                await _messageGroupAppService.UpdateMessageGroups(input.GroupIds,message.Id);
            }

            if (emailApprovers)
            {
                await EmailApprovers(message);
            }

            if (sendMessage)
            {
                await StartSendMessage((CreateUpdateMessageDto)message);
            }

            return message;
        }
    }
}

消息类

[Table("BmMessages")]
public class Message : FullAuditedEntity<int>
{
    public const int MaxTitleLength = 50;
    public const int MaxBodyLength = 2000;

    [required]
    [StringLength(MaxTitleLength)]
    public string Title { get; set; }

    [StringLength(MaxBodyLength)]
    public string Body { get; set; }

    [ForeignKey(nameof(ApprovingUserId))]
    public User ApprovingUser { get; set; }
    public long? ApprovingUserId { get; set; }

    [ForeignKey(nameof(StateLookUpId))]
    public LookUp StateLookUp { get; set; }
    public int StateLookUpId { get; set; }

    [ForeignKey(nameof(TypeLookUpId))]
    public LookUp TypeLookUp { get; set; }
    public int TypeLookUpId { get; set; }

    [ForeignKey(nameof(CompanyLookUpId))]
    public LookUp CompanyLookUp { get; set; }
    public int CompanyLookUpId { get; set; }

    public DateTime? ScheduledTime { get; set; }

    public Message(string title,string body = null)
    {
        Title = title;
        Body = body;
    }

    public Message(int typeLookUpId,int stateLookUpId,int companyLookUpId,string title,string body = null)
    {
        TypeLookUpId = typeLookUpId;
        StateLookUpId = stateLookUpId;
        CompanyLookUpId = companyLookUpId;
        Title = title;
        Body = body;
    }
}

MessageDto 类

[AutoMapFrom(typeof(Message))]
public class MessageDto : FullAuditedEntityDto<int>
{
    public string Title { get; set; }
    
    public string Body { get; set; }

    public DateTime ScheduledTime { get; set; }

    public User ApprovingUser { get; set; }
    public long? ApprovingUserId { get; set; }

    public int StateLookUpId { get; set; }
    public LookUp StateLookUp { get; set; }

    public int TypeLookUpId { get; set; }
    public LookUp TypeLookUp { get; set; }

    public int CompanyLookUpId { get; set; }
    public LookUp CompanyLookUp { get; set; }

    public int[] GroupIds { get; set; }

    public int RecipientCount { get; set; }
}

CreateUpdateMessageDto 类

[AutoMapTo(typeof(Message))]
public class CreateUpdateMessageDto : FullAuditedEntityDto<int>
{
    [required]
    [MaxLength(Message.MaxTitleLength)]
    public string Title { get; set; }

    [required]
    [MaxLength(Message.MaxBodyLength)]
    public string Body { get; set; }

    public DateTime ScheduledTime { get; set; }

    public User ApprovingUser { get; set; }
    public long? ApprovingUserId { get; set; }

    [required]
    public int StateLookUpId { get; set; }
    public LookUp StateLookUp { get; set; }

    [required]
    public int TypeLookUpId { get; set; }
    public LookUp TypeLookUp { get; set; }

    [required]
    public int CompanyLookUpId { get; set; }
    public LookUp CompanyLookUp { get; set; }

    public int[] GroupIds { get; set; }

    public static explicit operator CreateUpdateMessageDto(MessageDto messageDto)
    {
        return new CreateUpdateMessageDto()
        {
            Id = messageDto.Id,Title = messageDto.Title,Body = messageDto.Body,ScheduledTime = messageDto.ScheduledTime,StateLookUpId = messageDto.StateLookUpId,StateLookUp = messageDto.StateLookUp,TypeLookUpId = messageDto.TypeLookUpId,TypeLookUp = messageDto.TypeLookUp,CompanyLookUpId = messageDto.CompanyLookUpId,CompanyLookUp = messageDto.CompanyLookUp,GroupIds = messageDto.GroupIds
        };
    }
}

查找类

[Table("BmLookUps")]
public class LookUp : Entity
{
    [required]
    public string Title { get; set; }

    [required]
    public string Group { get; set; }

    public LookUp(string title,string group)
    {
        Title = title;
        Group = group;
    }
}

示例输入和结果(其中一些值在输入中为空,因为它们是在服务器端填充的)

Input
CreateUpdateMessageDto

ApprovingUser         = null,ApprovingUserId       = null,Body                  = "Lorem Ipsum",CompanyLookUp         = null,CompanyLookUpId       = 17,CreationTime          = {12/20/2020 11:52:08 PM},CreatorUserId         = null,DeleterUserId         = null,DeletionTime          = null,GroupIds              = {int[0]},Id                    = 73,IsDeleted             = false,LastModificationTime  = null,LastModifierUserId    = null,ScheduledTime         = {12/29/2020 11:08:00 PM},StateLookUp           = null,StateLookUpId         = 1,Title                 = "Test",TypeLookUp            = null,TypeLookUpId          = 8

Output
MessageDto

ApprovingUser         = null,DeleterUserId         = 6,DeletionTime          = {12/21/2020 1:33:52 AM},GroupIds              = null,IsDeleted             = true,// THIS SHOULD BE FALSE
LastModificationTime  = {12/20/2020 11:52:13 PM},LastModifierUserId    = 6,RecipientCount        = 0,TypeLookUpId          = 8

更新: 根据要求,这里是 GetLookup 方法的相关代码。它有 2 个重载。

public class LookUpAppService : ProjectAppServiceBase,ILookUpAppService
{
    private readonly IRepository<LookUp,int> _lookUpRepository;

    public LookUpAppService(IRepository<LookUp,int> lookUpRepository)
    {
        _lookUpRepository = lookUpRepository;
    }

    public async Task<LookUp> GetLookup(string Group,int Id)
    {
        return await _lookUpRepository.FirstOrDefaultAsync(l => l.Group == Group && l.Id == Id);
    }
        
    public async Task<LookUp> GetLookup(string Group,string Title)
    {
        return await _lookUpRepository.FirstOrDefaultAsync(l => l.Group == Group && l.Title == Title);
    }
}

解决方法

这可能是由于被跟踪实体中的更改跟踪信息发生冲突。

添加 .GetAll().AsNoTracking() 如下:

public async Task<LookUp> GetLookup(string Group,int Id)
{
 // return await _lookUpRepository.FirstOrDefaultAsync(l => l.Group == Group && l.Id == Id);
    return await _lookUpRepository.GetAll().AsNoTracking().FirstOrDefaultAsync(l => l.Group == Group && l.Id == Id);
}
    
public async Task<LookUp> GetLookup(string Group,string Title)
{
 // return await _lookUpRepository.FirstOrDefaultAsync(l => l.Group == Group && l.Title == Title);
    return await _lookUpRepository.GetAll().AsNoTracking().FirstOrDefaultAsync(l => l.Group == Group && l.Title == Title);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?