2011-06-06 110 views
1

TLDR总结我在与ASP.net MVC的InsertOnSubmit()函数中的几个问题ASP.net MVC LINQ到SQL插入问题

。如何在没有运行到关键约束的情况下构建新的对象并将其插入到数据库中?

步骤来重现

我已经先行一步,创造了我一直有3或那么大的问题一个简单的演示,也许有人可以帮助我在这里。

  1. 创建一个新的ASP.net MVC 2项目。
  2. 创建两个表格 - 具有一对多关系的实验和结果(如下所示)。
  3. 在主控制器内创建一个名为“RunExperiment”的新操作。
  4. 创建一个基本的linq-to-sql数据上下文。
  5. 让RunExperiment生成一个新的实验和结果,并通过新的数据上下文将它们插入到数据库中。

这个过程分崩离析很快,因为有一些神奇的需要发生,以防止重复的主键以确保依赖性保持不变。

Example image of database setup.

现在看看我的例子 “RunExperiment” 功能:

public ActionResult RunExperiment(string Title, string Scientist) 
    { 
     RepositoryDataContext RDC = new RepositoryDataContext(); 

     // Generate the experiment 
     Experiment thisExperiment = new Experiment(); 
     thisExperiment.experimentTitle = Title; 
     thisExperiment.experimentScientist = Scientist; 

     // Perform some work. 
     System.Threading.Thread.Sleep(500); 

     // Attempt to insert the experiment. 
     // Works once, fails subsequently due to duplicate primary key. 
     RDC.Experiments.InsertOnSubmit(thisExperiment); 
     RDC.SubmitChanges(); 

     for (int i = 0; i < 5; i++) 
     { 
      Result thisResult = new Result(); 
      thisResult.resultDate = DateTime.Now; 
      thisResult.resultTemp = i; 
      thisResult.Experiment = thisExperiment; 

      RDC.Results.InsertOnSubmit(thisResult); 
      RDC.SubmitChanges(); 
     }    

     return View("Index"); 
    } 

有什么想法?我知道这是基本的东西,但我试图远离复制Nerd Dinner模式,但我得到这些错误。

谢谢!

回答

2

你能确认你的experimentId列在SQL Server中设置了 - 我相信这应该被设置为:

[experimentId] [int] IDENTITY(1,1) NOT NULL 

我能够重现你的错误,当我删除了IDENTITY

在LINQ to SQL中,列的属性在“服务器数据类型”属性中应该有Int NOT NULL IDENTITY

+0

是的;那是错误的。非常感谢! – 2011-06-07 02:58:30

+0

+1这很可能是问题的原因。 – 2011-06-07 03:13:15

1

它试图每次再次插入thisExperiment,你可以做另一个周围,将结果添加到实验的结果属性?

或者,或者只是指定experimentID而不是链接它们?

2

首先,您需要解决我的一个难题 - 不要处理您的连接。

然后,利用LINQ自动为您执行外键关联。调用SubmitChanges()一次提交全部。

public ActionResult RunExperiment(string Title, string Scientist) 
{ 
    using (RepositoryDataContext RDC = new RepositoryDataContext()) 
    { 
     // Generate the experiment 
     Experiment thisExperiment = new Experiment(); 
     thisExperiment.experimentTitle = Title; 
     thisExperiment.experimentScientist = Scientist; 

     // Perform some work. 
     System.Threading.Thread.Sleep(500); 

     for (int i = 0; i < 5; i++) 
     { 
      Result thisResult = new Result(); 
      thisResult.resultDate = DateTime.Now; 
      thisResult.resultTemp = i; 

      // LINQ will automatically wire up the association during the insert 
      thisExperiment.Results.Add(thisResult); 
     } 

     // Attempt to insert the experiment, with associated results 
     RDC.Experiments.InsertOnSubmit(thisExperiment); 
     RDC.SubmitChanges(); 
    } 

    return View("Index"); 
} 

顺便说一句,这个数据访问片(你正在努力的一切)是LINQ to SQL,并不特定于ASP.NET MVC。您不必使用带有MVC的LINQ to SQL,并且您不必在LINQ to SQL中使用MVC。

+0

同意;这可能会更清洁。我实际上是遵循书呆子晚餐例子中使用的存储库模式。你是为每种方法创建/处理数据上下文,还是创建一个由模型/存储库使用的实例,然后保持活动状态? – 2011-06-07 02:59:35

+0

使用连接池 - 这就是它的用途。我不记得他们是如何在书呆子晚宴中做到的,但总的来说,最好的做法是只要你需要它就保持连接。 – GalacticCowboy 2011-06-07 20:55:33

+0

感谢银河。什么是我了解连接池的最佳方式?我正在做一些搜索,但空着。 – 2011-07-10 05:59:57