实体框架根据程序运行的位置创建不同的SQL
本文关键字:位置 创建 SQL 运行 框架 程序 实体 | 更新日期: 2023-09-27 18:17:48
我创建了一个小的c#控制台应用程序,它的唯一任务是解析xml文件并将结果放入数据库表中。我使用的是实体框架6.0和。net 4。
当我在本地计算机(Win7)上运行它时,一切都很好,但是当我在服务器(WS2008R2)上运行它时,它崩溃了。它是完全相同的文件只是复制/粘贴到服务器(即相同的数据库等)。
调试显示实体框架根据执行环境的不同创建了不同的sql查询。(见下文)
在本地计算机上(正常工作):
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 (Doesn ' t work):
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
我在这里有点迷路了。该怎么办?我认为您的数据库服务器版本没有为您的主键(Id)设置身份规范为Yes。所以它不会自动生成一个Id号,因为你没有传递它,这就是为什么它在null Id上出错。
如果你使用Code First(我很确定你是),然后注意不同版本的实体框架(不是不同版本的SQL Server)使用微妙的不同规则映射类到表。依赖于EF版本的一件事是,整数属性Id
是否自动映射到数据库中的IDENTITY
列,而无需您的任何规范。如果您的数据库创建时使用Id
作为常规的非标识列,并且您的代码更改了EF版本,因此现在需要一个标识列,那么事情就会中断。
解决方案是不要混合EF版本。选择一个版本,并坚持使用。确保该版本是您在本地计算机上使用的版本,也是您在服务器上使用的版本。确保实体框架dll的版本被复制到你的程序的安装目录,不要依赖全局安装的任何东西。
这就是我们问题的解决方案,我不知道为什么,但这里是:
我们忘了设置数据库初始化项。
Database.SetInitializer(new CustomContextInitializer());
现在调用:
public class CustomContextInitializer : IDatabaseInitializer<CustomProjectContext>
{
public void InitializeDatabase(CustomProjectContext context)
{
context.Database.Initialize(false);
}
}
我猜实体或。net正在做一些自己的后台操作,如果这部分缺失,这就是为什么我们在不同的环境下有不同的SQL。