10

我正在使用实体框架 5 - 代码优先。

我有一个要连接的数据库,现在已经存在了一段时间(我没有创建它)。有一个表叫T_Customers. 它包含所有客户的列表。它具有以下结构(仅部分显示):

Customer_id | numeric (5, 0) | auto increment | not null (not set as primary key)
FName | varchar(50) | not null
LName | varchar(50) | not null

我的Customer班级:

public class Customer : IEntity
{
     public int Id { get; set; }

     public string FirstName { get; set; }

     public string LastName { get; set; }
}

我的IEntity界面:

public interface IEntity
{
     int Id { get; set; }
}

我的数据库上下文类中有以下内容:

public class DatabaseContext : DbContext
{
     public DatabaseContext(string connectionString)
          : base(connectionString)
     {
     }

     public DbSet<Customer> Customers { get; set; }

     protected override void OnModelCreating(DbModelBuilder modelBuilder)
     {
          modelBuilder.Configurations.Add(new CustomerConfiguration());
     }

     public new DbSet<TEntity> Set<TEntity>()
          where TEntity : class, IEntity
     {
          return base.Set<TEntity>();
     }
}

我的客户配置类:

class CustomerConfiguration : EntityTypeConfiguration<Customer>
{
     internal CustomerConfiguration()
     {
          this.ToTable("T_Customers");
          this.Property(x => x.Id).HasColumnName("Customer_id");
          this.Property(x => x.FirstName).HasColumnName("FName");
          this.Property(x => x.LastName).HasColumnName("LName");
     }
}

我试图在我的实体声明中保持一致,我需要所有的 ID 都是整数。这个客户 ID 在数据库中是数字类型,现在我在尝试返回所有客户的列表时遇到了问题。如何从数据库数字类型映射到 C# 整数类型?我不会将班级的 ID 更改为可为空或十进制,我的 ID 始终是不可为空的整数。我也无法更改数据库。

我得到的错误是:

The 'Id' property on 'Customer' could not be set to a 'Decimal' value. 
You must set this property to a non-null value of type 'Int32'.
4

5 回答 5

7

指定列的数字类型

Property(x => x.Id).HasColumnName("Customer_id").HasColumnType("numeric");

生成数据库时,它将创建具有精度的数字列18,0。但是当您映射到现有数据库时,它可以与5,0数字列一起正常工作。

于 2013-02-11T13:32:23.870 回答
4

最简单的解决方案是使用另一个将映射到数据库字段的字段,并且 ID 属性将读取/写入该字段。像这样的东西:

public class Customer : IEntity
{
   public decimal CustomerID {get; set;}

   [NotMapped]
   public int Id 
   { 
      get { return (int)CustomerID; }
      set { CustomerID = (int)value; } 
   }

   public string FirstName { get; set; }

   public string LastName { get; set; }
}

将此新字段映射到数据库字段,使用

this.Property(x => x.CustomerID).HasColumnName("Customer_id");

并且 EF 将使用客户 id 字段,您的代码可以愉快地使用整数 id 字段。

于 2013-02-11T13:09:44.117 回答
0

在 .Net Core 中,您还可以使用 System.ComponentModel.DataAnnotations.Schema.ColumnAttribute 用底层列类型注释属性,例如,

    [Column(TypeName = "numeric(5, 0), not null")]
    public int Id { get; set; }

或者如果该列可以为空:

    [Column(TypeName = "numeric(5, 0), null")]
    public int? Id { get; set; }

我更喜欢@Sergey Berezovskiy 接受的答案,因为您实际上是在模型上而不是在其他地方(在 DbContext 中)进行注释。

ColumnAttribute 还可用于将属性映射到具有不同名称的列,例如,

    [Column("Identifier", TypeName = "numeric(5, 0), not null")]
    public int Id { get; set; }

ColumnAttribute 也可以在 .Net 框架中工作——我还没有测试过。

于 2020-11-13T09:58:59.590 回答
-1

确定代码首先应该是什么的另一个选择是 MS EF Powertools http://visualstudiogallery.msdn.microsoft.com/72a60b14-1581-4b9b-89f2-846072eff19d

您可以添加一个空项目,右键单击,EF 逆向工程代码首先从 DB。

您经常(并非总是)获得解决方案的良好开端。您是否尝试使用十进制?

public class Customer : IEntity
{
 public decimal Id { get; set; }

 public string FirstName { get; set; }

 public string LastName { get; set; }
}

如果您担心精度,您应该向 POCO 添加验证。

还有一些你可能喜欢的有趣的注释技巧。 http://geekswithblogs.net/danemorgridge/archive/2010/12/20/ef4-code-first-control-unicode-and-decimal-precision-scale-with.aspx 祝你好运

于 2013-02-11T13:48:17.747 回答
-2

您可以使用以下方法将其转换为 int:

 int myInt = Convert.Int32(numberFromDatabase);
于 2013-02-11T13:07:35.763 回答