【问题标题】:Datatype mismatch mapping existing database to EF将现有数据库映射到 EF 的数据类型不匹配
【发布时间】:2023-03-25 12:12:01
【问题描述】:

我正在使用现有的生产数据库创建 MVC 应用程序,但由于数据类型不匹配,我无法正确设置父类的虚拟属性。我的代码如下:

public class bill {

public int billId { get; set; }

.........

}


public class meter {

public int meterId { get; set; }

public int billId { get; set; }

.....

}


public class payment {

public int paymentId { get; set; }

public long billId { get; set; }

......
}

我在账单类中添加了以下内容:

public virtual ICollection<meter> Meters { get; set; }
public virtual ICollection<payment> Payments { get; set; }

我能够检索相关的计量表,但由于付款中billid 的数据类型为 long,我收到错误消息。有没有什么方法可以在不影响原始数据库的情况下正确映射代码优先模型?

我收到错误:

列名“bill_billId”无效。
列名“bill_billId”无效。
列名“bill_billId”无效。

尝试如下显示时:

 @foreach (var m in Model.Meters.Where(x => x.archived != true && x.meterUnitsUsed > 0))
 {
      <tr>
           <td>@Html.DisplayFor(x => m.meterSerialNumber)</td> 
           <td>@Html.DisplayFor(x => m.meterOpeningRead)</td>
           <td>@Html.DisplayFor(x => m.meterClosingRead)</td>
           <td>@Html.DisplayFor(x => m.meterUnitsUsed)</td>
           <td>@Html.DisplayFor(x => m.archived)</td>
           <td>@Html.DisplayFor(x => m.meterUnitType)</td>
           <td>@Html.DisplayFor(x => m.meterUnitPrice)</td>
           <td>@Html.DisplayFor(x => m.meterAmount)</td>

           @foreach (var i in Model.LiftsRefunds.Where(i => i.archived != true))
           {
                <td>@Html.DisplayFor(x => i.liftRefundDate)</td>
                <td>@Html.DisplayFor(x => i.liftRefundAmount)</td>
                <td>@Html.DisplayFor(x => i.liftType)</td>
           }
      </tr>
 }

当前使用的数据库设置错误,子类使用long数据类型,而父类的主键是int。是否有任何方法可以设置 EF 以忽略这一点并将 long 映射到 int 以便可以将付款作为虚拟属性引用?

【问题讨论】:

  • 好吧,你在 meter 类中有 billId 作为 int。不应该也很长吗?
  • 此外,每当您说遇到错误时,您应该始终提供准确的错误消息。表定义也会有所帮助。
  • meter 类工作正常,支付表的 billid 设置为 long,但在 billid 和 Meterid 中,它们都设置为 int,如果我最终更改上下文,我不想要正在更改的数据库
  • 在您的数据库中不是所有对billId 的引用都具有相同的数据类型吗?
  • 不是问题所在,它是一个现有的数据库,但我正在尝试将其用作 EF 上下文

标签: sql entity-framework linq-to-sql data-annotations


【解决方案1】:

我认为您有两个不同的问题。

===
首先,payment.billId 是对bill.billId 的引用,我们假设它们在 SQL Server 上有 2 个不同的列(每个表一个)。
1. 如果您忽略迁移(实际上您忽略迁移并且没问题),如果 SQL Server 中的数据类型不同于类的数据类型,即 SQL Server 上的 int 和 bigint 以及您的 int 和 int,您的程序也将正常工作类。
2.但是 SQL Server 不能建立从 bigint 列到 int 列的关系,所以在你的数据库中你不能有 bigint 和 int 两列或者你没有关系(你不必,EF无论如何都会起作用,但这不是一个好习惯)。

所以我建议你检查你在 SQL Server 上所做的事情,然后更改类的数据类型(即设置所有 int)并禁用迁移。

===
现在,为什么关于非现有字段的错误?
在您的课程中,您有一个映射配置问题。 您必须将payment.billId 属性与public virtual ICollection&lt;payment&gt; Payments { get; set; } 连接起来。 我使用流利的映射和每个类一个映射文件,所以在这种情况下,我在支付映射文件中编写

HasRequired(t => t.bill)
    .WithMany(t => t.Payments)
    .Map(d => d.MapKey("billId"));

你可以对属性做同样的事情。

【讨论】:

    【解决方案2】:

    对于错误:

    “payment”上的“billId”属性无法设置为“System.Int64”值。您必须将此属性设置为“System.Int32”类型的非空值

    按照说明here

    在您的 EDMX 中,如果您在 Y 表下单击 X 列,右键单击,单击属性,向下滚动到 Nullable,然后从 False 更改为 True。

    如果您收到“映射片段”错误,则必须从 EDMX 中删除表并重新添加它,因为在模型浏览器中它存储表属性以及刷新它的唯一方法(我知道)是从 .Store 下的模型浏览器中删除表,然后使用 Update Model from Database.. 命令检索它。

    有关详细信息,请参阅 MSDN 文档:How to: Update an .edmx File when the Database Changes (Entity Data Model Tools)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-13
      • 1970-01-01
      • 2012-10-08
      • 2012-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多