Entity Framework (EF6) + MySql 数据库优先模型多对多关系错误查询生成
Entity Framework (EF6) + MySql Database First Model Many to Many Relationship Wrong Query Generation
我有一个具有现有数据库结构和数据的项目。当前项目在 PHP + MySQL 上 运行,我正在尝试从 PHP 切换到 C# EF 6.0 + MySQL 数据库优先方法。
我已经安装了 NuGet 包(EF 6.0 和 MySQL.Data、MySQL.Web、MySQL.Data.Entity、MySQL.Data.Entities)并修改了我的 app.config根据使用 MySQL 数据提供者。到这个状态,一切正常,我可以从数据库生成模型,并可以在每个 table 上插入数据,没有任何问题,但多对多关系 tables。我创建了 2 个虚拟 tables,名称为 TableA 和 TableB 以及关系 table TableA_TableB 用于请求有关我的问题的帮助。
您可以在下面看到模型生成的屏幕截图:
生成的模型如下:
到目前为止,一切看起来都很好,但正如我在尝试在 TableA 和 TableB 之间插入关系时提到的那样,它失败了。你可以在下面看到我的 C# 代码:
public static void Create()
{
using (MainDataContext mainDataContext = new MainDataContext())
{
try {
mainDataContext.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
TableA tableA = new TableA();
tableA.Title = "My Title";
tableA.Description = "MyDescription";
mainDataContext.TableA.Add(tableA);
mainDataContext.SaveChanges();
TableB tableB = new TableB();
tableB.Title = "Table B Title";
tableB.Description = "Table B Description";
mainDataContext.TableB.Add(tableB);
mainDataContext.SaveChanges();
tableA.TableB.Add(tableB);
mainDataContext.SaveChanges();
}
catch (Exception ex)
{
}
}
}
前两个mainDataContext.SaveChanges();工作正常,但最后一个 mainDataContext.SaveChanges();关于我的 table 的 FK 抛出异常(我尝试了单个事务它也失败了)但是在我挖掘调试输出之后我遇到了异常的真正原因。我在我的数据上下文中打开调试输出,在这里您可以看到 EF 的插入语句的输出,您可以在下面看到它:
Opened connection at 11.1.2016 23:30:46 +02:00
Started transaction at 11.1.2016 23:30:46 +02:00
SET SESSION sql_mode='ANSI';INSERT INTO TableA
(
Title
,
Description
) VALUES (
@gp1,
@gp2);
SELECT
ID
FROM TableA
WHERE row_count() > 0 AND ID
=last_insert_id()
-- @gp1: 'My Title' (Type = String, IsNullable = false, Size = 8)
-- @gp2: 'MyDescription' (Type = String, IsNullable = false, Size = 13)
-- Executing at 11.1.2016 23:30:47 +02:00
-- Completed in 1 ms with result: EFMySqlDataReader
Committed transaction at 11.1.2016 23:30:47 +02:00
Closed connection at 11.1.2016 23:30:47 +02:00
Disposed transaction at 11.1.2016 23:30:47 +02:00
Opened connection at 11.1.2016 23:30:55 +02:00
Started transaction at 11.1.2016 23:30:55 +02:00
SET SESSION sql_mode='ANSI';INSERT INTO TableB
(
Title
,
Description
) VALUES (
@gp1,
@gp2);
SELECT
ID
FROM TableB
WHERE row_count() > 0 AND ID
=last_insert_id()
-- @gp1: 'Table B Title' (Type = String, IsNullable = false, Size = 13)
-- @gp2: 'Table B Description' (Type = String, IsNullable = false, Size = 19)
-- Executing at 11.1.2016 23:30:55 +02:00
-- Completed in 6 ms with result: EFMySqlDataReader
Committed transaction at 11.1.2016 23:30:55 +02:00
Closed connection at 11.1.2016 23:30:55 +02:00
Disposed transaction at 11.1.2016 23:30:55 +02:00
Opened connection at 11.1.2016 23:30:58 +02:00
Started transaction at 11.1.2016 23:30:58 +02:00
INSERT INTO (SELECT
TableA_TableB
.TableAID
,
TableA_TableB
.TableBID
FROM TableA_TableB
AS TableA_TableB
)(
TableAID
,
TableBID
) VALUES (
1,
1)
-- Executing at 11.1.2016 23:30:58 +02:00
-- Failed in 3 ms with error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(SELECT
TableA_TableB
.TableAID
,
TableA_TableB
.TableBID
FROM `TableA_Tab' at line 1
Closed connection at 11.1.2016 23:30:58 +02:00
Disposed transaction at 11.1.2016 23:30:58 +02:00
Exception thrown: 'System.Data.Entity.Infrastructure.DbUpdateException' in EntityFramework.dll
下面还有我的 table 的 DDL:
CREATE TABLE `TableA` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`Title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`Description` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `TableB` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`Title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`Description` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `TableA_TableB` (
`TableAID` int(10) unsigned NOT NULL,
`TableBID` int(10) unsigned NOT NULL,
KEY `TableA_TableB_TableAID` (`TableAID`),
KEY `TableA_TableB_TableBID` (`TableBID`),
CONSTRAINT `TableA_TableB_TableAID` FOREIGN KEY (`TableAID`) REFERENCES `TableA` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `TableA_TableB_TableBID` FOREIGN KEY (`TableBID`) REFERENCES `TableB` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
我想知道这是一个错误还是我做错了什么有人对我的问题有任何想法吗?
提前致谢!
问题是我的关系 table TableA_TableB 上缺少 PK 添加 PK (TableAID,TableBID) 后问题解决了。此外,在 EF 上使用 uint 会导致单一保存问题(您可以一个一个地保存 tables,在获取 ID 后您可以创建关系)
我有一个具有现有数据库结构和数据的项目。当前项目在 PHP + MySQL 上 运行,我正在尝试从 PHP 切换到 C# EF 6.0 + MySQL 数据库优先方法。
我已经安装了 NuGet 包(EF 6.0 和 MySQL.Data、MySQL.Web、MySQL.Data.Entity、MySQL.Data.Entities)并修改了我的 app.config根据使用 MySQL 数据提供者。到这个状态,一切正常,我可以从数据库生成模型,并可以在每个 table 上插入数据,没有任何问题,但多对多关系 tables。我创建了 2 个虚拟 tables,名称为 TableA 和 TableB 以及关系 table TableA_TableB 用于请求有关我的问题的帮助。
您可以在下面看到模型生成的屏幕截图:
生成的模型如下:
到目前为止,一切看起来都很好,但正如我在尝试在 TableA 和 TableB 之间插入关系时提到的那样,它失败了。你可以在下面看到我的 C# 代码:
public static void Create()
{
using (MainDataContext mainDataContext = new MainDataContext())
{
try {
mainDataContext.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
TableA tableA = new TableA();
tableA.Title = "My Title";
tableA.Description = "MyDescription";
mainDataContext.TableA.Add(tableA);
mainDataContext.SaveChanges();
TableB tableB = new TableB();
tableB.Title = "Table B Title";
tableB.Description = "Table B Description";
mainDataContext.TableB.Add(tableB);
mainDataContext.SaveChanges();
tableA.TableB.Add(tableB);
mainDataContext.SaveChanges();
}
catch (Exception ex)
{
}
}
}
前两个mainDataContext.SaveChanges();工作正常,但最后一个 mainDataContext.SaveChanges();关于我的 table 的 FK 抛出异常(我尝试了单个事务它也失败了)但是在我挖掘调试输出之后我遇到了异常的真正原因。我在我的数据上下文中打开调试输出,在这里您可以看到 EF 的插入语句的输出,您可以在下面看到它:
Opened connection at 11.1.2016 23:30:46 +02:00 Started transaction at 11.1.2016 23:30:46 +02:00
SET SESSION sql_mode='ANSI';INSERT INTO
TableA
(Title
,Description
) VALUES ( @gp1, @gp2); SELECTID
FROMTableA
WHERE row_count() > 0 ANDID
=last_insert_id() -- @gp1: 'My Title' (Type = String, IsNullable = false, Size = 8) -- @gp2: 'MyDescription' (Type = String, IsNullable = false, Size = 13) -- Executing at 11.1.2016 23:30:47 +02:00 -- Completed in 1 ms with result: EFMySqlDataReaderCommitted transaction at 11.1.2016 23:30:47 +02:00 Closed connection at 11.1.2016 23:30:47 +02:00 Disposed transaction at 11.1.2016 23:30:47 +02:00 Opened connection at 11.1.2016 23:30:55 +02:00 Started transaction at 11.1.2016 23:30:55 +02:00
SET SESSION sql_mode='ANSI';INSERT INTO
TableB
(Title
,Description
) VALUES ( @gp1, @gp2); SELECTID
FROMTableB
WHERE row_count() > 0 ANDID
=last_insert_id()-- @gp1: 'Table B Title' (Type = String, IsNullable = false, Size = 13) -- @gp2: 'Table B Description' (Type = String, IsNullable = false, Size = 19) -- Executing at 11.1.2016 23:30:55 +02:00 -- Completed in 6 ms with result: EFMySqlDataReader
Committed transaction at 11.1.2016 23:30:55 +02:00 Closed connection at 11.1.2016 23:30:55 +02:00 Disposed transaction at 11.1.2016 23:30:55 +02:00 Opened connection at 11.1.2016 23:30:58 +02:00 Started transaction at 11.1.2016 23:30:58 +02:00
INSERT INTO (SELECT
TableA_TableB
.TableAID
,TableA_TableB
.TableBID
FROMTableA_TableB
ASTableA_TableB
)(TableAID
,TableBID
) VALUES ( 1, 1)-- Executing at 11.1.2016 23:30:58 +02:00
-- Failed in 3 ms with error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(SELECT
TableA_TableB
.TableAID
,TableA_TableB
.TableBID
FROM `TableA_Tab' at line 1Closed connection at 11.1.2016 23:30:58 +02:00 Disposed transaction at 11.1.2016 23:30:58 +02:00 Exception thrown: 'System.Data.Entity.Infrastructure.DbUpdateException' in EntityFramework.dll
下面还有我的 table 的 DDL:
CREATE TABLE `TableA` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`Title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`Description` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `TableB` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`Title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`Description` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `TableA_TableB` (
`TableAID` int(10) unsigned NOT NULL,
`TableBID` int(10) unsigned NOT NULL,
KEY `TableA_TableB_TableAID` (`TableAID`),
KEY `TableA_TableB_TableBID` (`TableBID`),
CONSTRAINT `TableA_TableB_TableAID` FOREIGN KEY (`TableAID`) REFERENCES `TableA` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `TableA_TableB_TableBID` FOREIGN KEY (`TableBID`) REFERENCES `TableB` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
我想知道这是一个错误还是我做错了什么有人对我的问题有任何想法吗?
提前致谢!
问题是我的关系 table TableA_TableB 上缺少 PK 添加 PK (TableAID,TableBID) 后问题解决了。此外,在 EF 上使用 uint 会导致单一保存问题(您可以一个一个地保存 tables,在获取 ID 后您可以创建关系)