如何在实体框架代码中首先映射不同数据类型的列和标识属性

时间:2013-02-11 13:04:19

标签: c# entity-framework entity-framework-5

我正在使用Entity Framework 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在数据库中的类型为numeric,现在我在尝试返回所有客户的列表时遇到问题。如何从数据库数字类型映射到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'.

5 个答案:

答案 0 :(得分:6)

指定列

的数字类型
Property(x => x.Id).HasColumnName("Customer_id").HasColumnType("numeric");

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

答案 1 :(得分: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字段。

答案 2 :(得分: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 Framework中工作-我尚未对其进行测试。

答案 3 :(得分:-1)

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

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

您经常(并非总是)为解决方案提供良好的开端。 你尝试过使用小数吗?

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

 public string FirstName { get; set; }

 public string LastName { get; set; }
}

如果您关注精度,则应该向POCO添加验证。

您可能也喜欢一些有趣的Anotation黑客攻击。 http://geekswithblogs.net/danemorgridge/archive/2010/12/20/ef4-code-first-control-unicode-and-decimal-precision-scale-with.aspx 祝你好运

答案 4 :(得分:-2)

您可以使用以下命令将其转换为int:

 int myInt = Convert.Int32(numberFromDatabase);