目前在EF Core 6上.如果这很重要,我使用的是MySQL数据库.

我有两个数据库模型,它们是基于当前生产环境中的现有遗留数据库自动生成的.我的任务是将这些数据从遗留数据库导入到新的数据库模式中.因为这是在生产中,所以我不能为了我要问的问题而修改数据库的模式.

该数据库有相关的表.我们称它们为Widget和WidgetBlocker.Widget有一个uint类型的主键,并且与WidgetBlocker存在多对多关系.WidgetBlocker有一个指向Widget的外键,但数据类型(我不知道原因)是可以为空的int.这意味着我的课程看起来像这样.

public class Widget
{
   public uint WidgetId { get; set; }
.
.
.
}

public class WidgetBlocker
{
   public uint WidgetBlockerId { get; set; }
   public int? WidgetId { get; set; }
.
.
.

}

我想向Widget添加一个导航属性,如下所示:

public ICollection<WidgetBlocker> Blockers { get; set; }

然后,我将设置DbContext OnModel创建,如下所示:

modelBuilder.Entity<Widget>(entity =>
{
   entity.HasMany(widget => widget.Blockers).WithMany().HasForeignKey(widgetBlocker => widgetBlocker.WidgetId);
});

代码构建得很好,但我得到一个运行时错误,指出:

与外键属性int的关系?不能指向主键单元?因为它是不兼容的.为此关系配置一个主键或一组具有兼容类型的外键属性.

有没有办法在不修改表的模式的情况下遵循这些说明(配置一个主键或一组具有兼容类型的外键属性)?如果没有,有没有办法设置导航属性?也许是通过类上的一个属性,该属性允许数据库具有一种数据类型,而数据模型具有另一种数据类型?或者,除了数据类型问题,我可能做了一些不正确的事情?

推荐答案

Widget的数据类型为"int(10)unsign"和"int(11)Null"

根据外键的MySQL documentation(重点是我的):

外键和被引用键中的对应列必须具有类似的数据类型.The size 100 of fixed precision types such as INTEGER and DECIMAL 101.字符串类型的长度不必相同.对于非二进制(字符)字符串列,字符集和排序规则必须相同.

这意味着通常不能在这两列上定义FK,更不用说EF了.请注意,您的代码(如果它可以工作的话)应该已经创建了一个FK,这是一个方案修改.

您需要调整数据库中的类型(代码优先或数据库优先,取决于您的情况和目标),然后才能添加此关系.

在此之前,您将被绑定到手动联接和/或其他变通方法(视图等)

Csharp相关问答推荐

在包含空项的列表上使用具有断言T的摘要表

如何打印已添加到List的Linq值,而不是C#中的:System.Collections.Generic.List ' 1[System.Int32]?

如何从顶部提取发票号作为单词发票后的第一个匹配

AutoMapper -如何为两个不同的用例设置单个映射?

Rider将.NET安装在哪里

使用两个不同的枚举作为Switch语句中的CASE生成唯一值

Automapper 12.x将GUID映射到字符串

为什么C#认为这个非托管 struct 有一个重叠

取决于您的数据量的多个嵌套循环

如何通过寻找向量长度来优化两个循环?

在.NET 7.0 API控制器项目中通过继承和显式调用基类使用依赖项注入

EFR32BG22 BLE在SPP模式下与PC(Windows 10)不连接

当我将`ConcurentDictionary`转换为`IDictionary`时,出现了奇怪的并发行为

Postgres ENUM类型在第一次运行时对Dapper不可见

在集成测试中可以在模拟InMemory数据库中设定数据种子

如何在特定环境中运行dotnet测试?

用于请求用户返回列表的C#Google API

C#使用相同内存的多个数组

使用Try-Catch-Finally为API端点处理代码--有什么缺点?

MudBlazor MudTabs-->;选项卡内容高度