将现有数据库映射到 EF 的数据类型不匹配

Datatype mismatch mapping existing database to EF

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

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; }

......
}

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

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

我能够检索相关的仪表,但由于支付中的 billid 长数据类型,我收到了一个错误。在我对代码优先模型的更改不影响原始数据库的情况下,是否有任何方法可以正确映射它?

我收到错误:

Invalid column name 'bill_billId'.
Invalid column name 'bill_billId'.
Invalid column name '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>
 }

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

错误:

The 'billId' property on 'payment' could not be set to a 'System.Int64' value. You must set this property to a non-null value of type 'System.Int32'

按照说明进行操作 here:

In your EDMX, if you go under your Y table and click on X column, right-click, click on Properties, scroll down to Nullable and change from False to True.

If you get a "mapping fragment" error, you'll have to delete the table from the EDMX and re-add it, because in the Model Browser it stores the table properties and the only way to refresh that (that I know of) is to delete the table from the Model Browser under .Store then retrieving it using Update Model from Database.. command.

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

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

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

所以我建议你检查你在 SQL 服务器上做什么,然后更改 classes 的数据类型(即设置所有 int)并禁用迁移。

===
现在,为什么关于不存在字段的错误?
在您的 classes 中,您遇到了映射配置问题。 您必须将 payment.billId 属性 与 public virtual ICollection<payment> Payments { get; set; } 连接起来。 我使用流畅的映射和每个 class 一个映射文件,所以在这种情况下,在付款的映射文件中我写

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

您可以对属性执行相同的操作。