LINQ to SQL Repository模式自动增量问题

时间:2011-05-05 09:52:47

标签: c# sql-server linq-to-sql asp.net-mvc-2 repository-pattern

我有一个奇怪的问题,我正在试图弄清楚它是我的代码还是某些东西搞砸了数据库。我有一个表WebClienteLogin,它有一个属性Id(主键,自动增量)。我在用户在网站上注册时插入新记录。

昨天早上,最后一位注册用户的价值ID达到9000左右,下午开始以有趣的方式跳转,所以下一位用户有Id 1200,25000 .....并达到290000.但是,今天它继续正常(递增1)。根据统计数据,我发现当有大量用户同时注册时会发生这种情况。

使用的技术:SQL Server 2008 R2,ASP.NET MVC2,.NET 3.5

我正在使用Repository模式和LINQ。这是我对其中一个存储库的实现。

public SQLWebClientLoginRepository(string connectionString)
{
                dataContext = new DataContext(connectionString);
                tabla = dataContext.GetTable<WebClientLogin>(); 
}


public bool Save(WebClientLogin user)
            {
                bool success = true;            

                try
                {
                    if (user.Id == 0)
                    {
                        tabla.InsertOnSubmit(user);
                    }
                    else if (tabla.GetOriginalEntityState(user) == null)
                    {
                        tabla.Attach(user);
                        tabla.Context.Refresh(RefreshMode.KeepCurrentValues, user);
                    }
                    tabla.Context.SubmitChanges();  
                }
                catch
                {
                    ......
                }

                return success;
     }

此外,用户还附加了其他对象,因此它会将INSERT插入到两个表中,LINQ将其包装到事务中。

  var user = new WebClientLogin();
  // assigning other properties
  user.WebClient = new WebClient { // setting propeties }

  webClientLoginRepository.Save(user)

在日志中我得到例外:

试图删除a WebClientLogin和WebCLient之间的关系 但是,关系的一个外键 (WebClient.WebCLientLogin_id)不能设置为null。“异常

我不知道为什么这样做!有没有经历过任何相似的事情?

3 个答案:

答案 0 :(得分:0)

启动数据库状态:

WebClientLogin
ID = 900

WebClient
ID = 1, WebClientLogin_Id = 900

在修改前的内存中:

WebClientLogin
ID = 900

WebClient
ID = 1, WebClientLogin_Id = 900, WebClientLogin = that instance with 900

检查WebClientLogin的WebClient属性。在SubmitChanges时的内存中:

WebClientLogin
ID = 900

WebClient (original instance)
ID = 1, WebClientLogin_Id = 900, WebClientLogin = null

WebClient  (new instance!)
ID = 0, WebClientLogin_Id = 900, WebClientLogin = that instance with 900

尝试更改数据库:

WebClientLogin (no change)
ID = 900

WebClient (new row, inserted)
ID = 2, WebClientLogin_Id = 900

WebClient (original row, updated)
ID = 1, WebClientLogin_Id = 900 -> null  (error, rollback transaction)

答案 1 :(得分:0)

我稍微修改了一下存储库,但似乎它解决了这个问题,但现在又有了另一个。

public bool Save(WebClientLogin login, WebClient client)
        {
            var created = false;

            using (var transaction = new TransactionScope())
            {
                try
                {
     // insert WebClientLogin first
                    tablalogin.InsertOnSubmit(login);
                    dataContext.SubmitChanges();

     // insert WebClient second
                    client.WebClientLogin_id = login.Id;
                    tablacliente.InsertOnSubmit(client);

                    dataContext.SubmitChanges();
                    created = true;
                    transaction.Complete();
                }
                catch (Exception ex)
                {
                    //
                }
            }
            return created;
        }

当用户数量很大时,我只插入WebClientLogin但没有WebClient 我得到了这个例外:

Internal .Net Framework Data Provider error 60

答案 2 :(得分:0)

嗯......整个应用程序都给出了许多其他奇怪的异常。所以我们访问了我们的主人,我们发现了导致它的原因。主机配置了3个专用Web服务器和1个数据库服务器。他们为Web服务器配置了负载均衡器和dfs。他们关闭了3台服务器中的2台并进行了压力测试。从那时起,没有错误/异常或错误的交易。看起来像服务器问题。