C# EF取芯两次相同的数据

C# EF取芯两次相同的数据,c#,razor-pages,asp.net-core-2.2,ef-core-2.2,C#,Razor Pages,Asp.net Core 2.2,Ef Core 2.2,我有一个向系统成员发送电子邮件的功能。他们将收到哪封电子邮件取决于不同的情况 最近我发现,它有时会发送给同一个人两次 我的代码-简化: In my startup.cs: [...] services.AddDbContext<DBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("App"))); [...] My page: namespace

我有一个向系统成员发送电子邮件的功能。他们将收到哪封电子邮件取决于不同的情况

最近我发现,它有时会发送给同一个人两次

我的代码-简化:

In my startup.cs:

[...]

services.AddDbContext<DBContext>(options => options.UseSqlServer(Configuration.GetConnectionString("App")));

[...]


My page:

namespace MyApp.Pages
{

    public class MemberMailsModel : PageModel
    {

        private readonly DBContext _dbContext;
        private readonly IHttpClientFactory _httpClientFactory;

        public MemberMailsModel(DBContext dbContext, IHttpClientFactory httpClientFactory)
        {
            _dbContext = dbContext;
            _httpClientFactory = httpClientFactory;
        }

        public async Task<PageResult> OnGetAsync()
        {

            var httpClient = _httpClientFactory.CreateClient("SendInBlue");
            var members = await _dbContext.Members.Include(x => x.Logs).Where(x => x.ConsentDate == null).AsNoTracking().ToListAsync();

            foreach (var member in members)
            {

                bool mail1sent = member.Logs.Any(x => x.Action == "Mail1Sent");
                bool mail2sent = member.Logs.Any(x => x.Action == "Mail2Sent");
                bool mail3sent = member.Logs.Any(x => x.Action == "Mail3Sent");

                if (!mail1sent)
                {                
                    var sibMail = await httpClient.PostAsync(...);
                    sibMail.Dispose();

                    var log = new Log
                    {
                        Date = DateTime.Now,
                        Action = "Mail1Sent",
                        Text = "Mail #1 sent",
                        MemberId = member.Id
                    }
                    _dbContext.Add(log);
                }
                else if (!mail2sent && mail1sent)
                {                
                    var sibMail = await httpClient.PostAsync(...);
                    sibMail.Dispose();

                    var log = new Log
                    {
                        Date = DateTime.Now,
                        Action = "Mail2Sent",
                        Text = "Mail #2 sent",
                        MemberId = member.Id
                    }
                    _dbContext.Add(log);
                }
                else if (!mail3sent && mail2sent)
                {                
                    var sibMail = await httpClient.PostAsync(...);
                    sibMail.Dispose();

                    var log = new Log
                    {
                        Date = DateTime.Now,
                        Action = "Mail3Sent",
                        Text = "Mail #3 sent",
                        MemberId = member.Id
                    }
                    _dbContext.Add(log);
                }

                await _dbContext.SaveChangesAsync();

            }

            return Page();

        }

    }

}
在my startup.cs中:
[...]
services.AddDbContext(options=>options.UseSqlServer(Configuration.GetConnectionString(“App”));
[...]
我的页面:
名称空间MyApp.Pages
{
公共类成员MailsModel:PageModel
{
私有只读dbcontextu DBContext;
私有只读IHttpClientFactory\U httpClientFactory;
公共成员MailsModel(DBContext DBContext,IHttpClientFactory httpClientFactory)
{
_dbContext=dbContext;
_httpClientFactory=httpClientFactory;
}
公共异步任务OnGetAsync()
{
var httpClient=_httpClientFactory.CreateClient(“SendInBlue”);
var members=await_dbContext.members.Include(x=>x.Logs).Where(x=>x.approvedate==null).AsNoTracking().ToListAsync();
foreach(成员中的var成员)
{
bool mail1sent=member.Logs.Any(x=>x.Action==“mail1sent”);
bool mail2sent=member.Logs.Any(x=>x.Action==“mail2sent”);
bool mail3sent=member.Logs.Any(x=>x.Action==“mail3sent”);
如果(!mail1sent)
{                
var sibMail=wait-httpClient.PostAsync(…);
sibMail.Dispose();
var log=新日志
{
日期=日期时间。现在,
Action=“Mail1Sent”,
Text=“已发送邮件#1”,
MemberId=成员。Id
}
_添加(日志);
}
else if(!mail2sent&&mail1sent)
{                
var sibMail=wait-httpClient.PostAsync(…);
sibMail.Dispose();
var log=新日志
{
日期=日期时间。现在,
Action=“Mail2Sent”,
Text=“已发送邮件#2”,
MemberId=成员。Id
}
_添加(日志);
}
else if(!mail3sent&&mail2sent)
{                
var sibMail=wait-httpClient.PostAsync(…);
sibMail.Dispose();
var log=新日志
{
日期=日期时间。现在,
Action=“Mail3Sent”,
Text=“已发送邮件#3”,
MemberId=成员。Id
}
_添加(日志);
}
wait_dbContext.saveChangesSync();
}
返回页();
}
}
}
我可以在我的自定义日志函数中看到,一些成员两次收到相同的电子邮件,并在完全相同的时间戳下两次添加到日志中,就好像该成员在查询中两次一样

它可以发生在任何随机成员的任何条件上


这是怎么回事?

由于这些问题,不要在get请求中执行任何有副作用的操作是一种古老的智慧。也就是说,问题很可能在于如何以及何时调用此。。您确定发送到此页面的请求不超过一个吗?
\u dbContext.Members.Include(x=>x.Logs)
如果一个“成员”有多个“日志”,您是否会返回具有相同成员信息的多个记录?相当于
Select*from Members m JOIN Logs l on l.memberid=m.memberid
或类似内容that@MatJ我很高兴你能更具体一点关于副作用的意思是什么?该页每小时仅由服务器上的任务调用一次。服务器使用限制参数调用url,但不能手动调用。@Mads创建数据(
\u dbContext.Add(log)
)或发送电子邮件将是
GET
操作的副作用。谢谢@user2051770。那么什么是最佳实践呢?不,一个成员只被拉入一次,即使该成员有许多日志。:)