实体框架根据程序的运行位置创建不同的SQL

时间:2014-08-12 09:22:28

标签: c# sql .net sql-server entity-framework-6

我创建了一个小型C#控制台应用程序,其唯一任务是解析XML文件并将结果放入数据库表中。我正在使用Entity framework 6.0和.NET 4。

当我在我的本地计算机(Win7)上运行它时,一切都很好但是当我在服务器(WS2008R2)上运行它时它会崩溃。它是完全相同的文件,只是复制/粘贴到服务器(即相同的数据库等)。

调试显示,实体框架根据执行的环境创建不同的SQL查询。 (见下文)

ON LOCAL COMPUTER(正常工作):

INSERT [dbo].[Accessories]([Id], [Name], [Category], [Price], [Description], [Phone_Id])
VALUES (@0, @1, @2, @3, @4, NULL)
@0: '1018' (Type = Int32)
@1: 'H141/A Headset Duoset' (Type = String, Size = -1)
@2: 'Headset Fixed Lines' (Type = String, Size = -1)
@3: '1563' (Type = Int32)
@4: 'H141/A DuoSet™, Plantronics headset.' (Type = String, Size = -1)
Executing 
Completed in 19 ms with result: 1

ON SERVER(不起作用):

INSERT [dbo].[Accessories]([Name], [Category], [Price], [Description], [Phone_Id])
VALUES (@0, @1, @2, @3, NULL)
SELECT [Id]
FROM [dbo].[Accessories]
WHERE @@ROWCOUNT > 0 AND [Id] = scope_identity()
@0: 'H141/A Headset Duoset' (Type = String, Size = -1)
@1: 'Headset Fixed Lines' (Type = String, Size = -1)
@2: '1563' (Type = Int32)
@3: 'H141/A DuoSet™, Plantronics headset.' (Type = String, Size = -1)
Executing 
Failed in 1 ms with error: Cannot insert the value NULL into column 'Id', table 'Sales.dbo.Accessories'; column does not allow nulls. INSERT fails.
The statement has been terminated.

应用程序中的实际代码:

           try
           {
               XmlNodeList xNodeList = xDoc.SelectNodes("accessories/child::node()");
               foreach (XmlNode xNode in xNodeList)
               {
                   if (xNode.Name == "accessory")
                   {
                       var accessory = new Accessory();
                       accessory.Id = Convert.ToInt32(xNode.Attributes["id"].Value);
                       foreach (XmlNode childNode in xNode.ChildNodes)
                       {
                           if (childNode.Name == "name")
                           {
                               accessory.Name = childNode.InnerText;
                           }
                           if (childNode.Name == "category")
                           {
                               accessory.Category = childNode.InnerText;
                           }
                           if (childNode.Name == "description")
                           {
                               accessory.Description = childNode.InnerText;
                           }
                           if (childNode.Name == "price")
                           {
                               accessory.Price = Convert.ToInt32(childNode.InnerText);
                           }
                       }
                       _db.Add(accessory);
                   }
               }
               _db.SaveChanges();

SQL-server是MSSQL。

我有点迷失在这里......该怎么办?

3 个答案:

答案 0 :(得分:0)

我认为您的服务器版本的数据库没有为您的主键(Id)将标识规范设置为“是”。所以它不是自动生成一个Id号码,因为你没有通过它,这就是为什么它在空ID上出错。

答案 1 :(得分:0)

如果你正在使用Code First(我很确定你是),那么请注意不同版本的Entity Framework(不同版本的SQL Server)使用微妙的不同规则进行映射类到表。取决于确切的EF版本的一件事是整数属性Id是否自动,没有任何规范,映射到数据库中的IDENTITY列。如果您的数据库是使用Id作为常规非标识列创建的,并且您的代码更改了EF版本,以便它现在需要标识列,那么事情就会中断。

解决方案是不混合EF版本。选择一个版本,坚持下去。确保该版本是您在本地计算机上使用的版本,以及您在服务器上使用的版本。确保将Entity Framework DLL的版本复制到程序的安装目录中,不要依赖于全局安装的任何内容。

答案 2 :(得分:0)

这是我们问题的解决方案,我不知道为什么,但这里是:

我们忘了设置数据库初始化程序。

Database.SetInitializer(new CustomContextInitializer());

现在要求:

public class CustomContextInitializer : IDatabaseInitializer<CustomProjectContext>
{        
    public void InitializeDatabase(CustomProjectContext context)
    {
        context.Database.Initialize(false);
    }
}

我想Entity或.NET正在做一些自己的后台操作,如果缺少这部分,那就是为什么我们在不同的环境中得到不同的SQL。