【问题标题】:ASP.Net - Mvc5 : LINQ , Saving duplicate record problemASP.Net - Mvc5:LINQ,保存重复记录问题
【发布时间】:2018-10-31 11:45:23
【问题描述】:

我正在编写每日计数器。数据库计数器表为空。如果某人是我当天的第一个访客,那么我正在向数据库中添加一条记录,并且我正在设置 counter=1;在此之后,当其他访客访问当天,那么我正在增加我的计数器++并且我正在更新记录。

所以我的记录一定是这样的:

日期:2018-10-01柜台:23

日期:2018-10-02柜台:65

日期:2018-10-03柜台:20

日期:2018-10-04柜台:89

我的问题是:如果网站同时获得访问者,linq 会在同一天保存 2 条记录。像这样:

日期:2018-10-01柜台:23

Date:2018-10-02 counter:1 //第一条记录:counter=1

Date:2018-10-02 counter:65 //第二条记录:counter=65

日期:2018-10-03柜台:20

Date:2018-10-04 counter:1 //第一条记录

Date:2018-10-04 counter:89 //第二条记录

日期必须是唯一的。我该如何解决这个问题?我的代码如下。非常感谢。

public static int IncreaseCounter_DailySiteVisitors()
    {
        int counter = 0;
        using (var context = new MyProjectEntities())
        {
            try
            {
                string format = "dd.MM.yyyy";
                DateTime Today = DateTime.Now;
                var obj = (from record in context.CounterDailySiteVisitor
                           where 
                           record.DateRecord != null 
                           && record.DateRecord.HasValue 
                           && record.DateRecord.Value.Year == Today.Year 
                           && record.DateRecord.Value.Month == Today.Month
                           && record.DateRecord.Value.Day == Today.Day
                           select record).FirstOrDefault();



               //var obj = context.CounterDailyVisitor.Where(x => x.DateRecord != null && ((DateTime)x.DateRecord).ToString("yyyy.MM.dd") == DateTime.Now.ToString("yyyy.MM.dd")).FirstOrDefault();
                if (obj != null)
                {
                    counter = obj.Count ?? 0;
                    counter++;
                    obj.Count = counter;
                    context.SaveChanges();
                }
                else
                {
                    var newRecordObj = context.CounterDailySiteVisitor.Create();
                    newRecordObj.Count = 1;
                    newRecordObj.DateRecord = Today;
                    context.CounterDailySiteVisitor.Add(newRecordObj);
                    context.SaveChanges();
                }
            }
            catch (Exception e)
            {

            }


        }
        return counter;
    }

【问题讨论】:

  • 如果这是并发问题,我不是 100% 相信它是,但如果是,那么在这个过程中添加一个锁......

标签: c# asp.net asp.net-mvc linq model-view-controller


【解决方案1】:

同时被两个线程命中的可能性非常低。 但我想从技术上讲它可以,所以你需要把它锁起来

类似下面...

public static int IncreaseCounter_DailySiteVisitors()
{
    private readonly object somethingObject = new object();

    var context = new MyProjectEntities() 

    var today = DateTime.Now;
    var todaysRecord = context.CounterDailyVisitor
                .SingleOrDefault(x => x.DateRecord.Year == Today.Year
                            && x.DateRecord.Month == Today.Month
                           && x.DateRecord.Day == Today.Day
                );
    if (todaysRecord != null)
    {
       //the existing count + 1
       todaysRecord.Count = todaysRecord.Count++;
    }
    else
    {

       Lock(somethingObject)
       {
           //recheck
           var todaysRecord = context.CounterDailyVisitor
                   .SingleOrDefault(x => x.DateRecord.Year == Today.Year
                       && x.DateRecord.Month == Today.Month
                    && x.DateRecord.Day == Today.Day
                );

           if (todaysRecord != null)
           {
               //the existing count + 1
               todaysRecord.Count = todaysRecord.Count++;
           }
           else
           {
            var newRecordObj = new CounterDailyVisitor();
            newRecordObj.Count = 1;
            newRecordObj.DateRecord =  DateTime.Now; //this shouldnt be nullable

            context.CounterDailySiteVisitor.Add(newRecordObj);
           }    
        }
    }
    context.SaveChanges();
}

【讨论】:

    【解决方案2】:

    这是一个相当常见的并发问题,即竞态条件。您将不得不Lock 围绕读取并随后更新/插入值的代码。或者你应该调用一个存储过程并将所有逻辑都放在存储过程中。

    如果您计划使用网络场或运行此 MVC 应用程序的多个实例,Lock 会出现一系列问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-29
      • 2019-02-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-02
      • 1970-01-01
      相关资源
      最近更新 更多