具有用户表值类型的实体框架

本文关键字:实体 框架 类型 用户 | 更新日期: 2023-09-27 18:09:15

我有以下场景:

  • 具有复杂类型Period的名为Degree的实体
  • 我想使用的功能在sql User-Defined Table type

实体代码

public class Degree {
    public string Institution {get;set;}
    public string Major {get; set;}
    public Country Country {get; set;}
    public Period StartOn {get; set;}
    public Period EndOn {get; set;}    
}
public class Period {
    public int Year {get; set;}
    public int Month {get; set;}
    public bool IsPresent {get; set;}
}

public class Context: DbContext
{
    public DbSet<Degree> Degrees {get; set;}
    public override void OnModelCreating(DbModelBuilder modelBuilder)
    {        
        modelBuilder.Entity<Degree>()
                    .Property(t => t.StartOn).HasColumnType("udt_period");
    }
}

**错误**

错误CS0453类型'Period'必须是一个非空的值类型以便将其用作泛型类型或方法中的参数'T'"StructuralTypeConfiguration.Property(表达式>)"

如何让实体框架创建用户定义的表类型,并使用StartOnEndOn作为udt_period

任何帮助都是非常感谢的

具有用户表值类型的实体框架

不能将数据库表中的列定义为用户定义表类型,通常用作存储过程的参数。

您可以从SQL服务器端定义一个用户定义的数据类型,例如varchar(8),您可以在您的解决方案中使用它。

StartOn的值可能为09/2014Sep 2014EndOn的值可能为11/2015Nov 2015Present,如果您想使用09/2014格式,则将数据类型设置为varchar(7)而不是varchar(8)

为了应用上述建议,您的代码应该按照以下方式修改:

public class Degree {
    public string Institution {get;set;}
    public string Major {get; set;}
    public Country Country {get; set;}
    public string StartOn {get; set;}
    public string EndOn {get; set;}    
}

如果你使用代码优先的方法,你仍然可以从你的应用程序端创建用户定义的数据类型,如果你使用Migrations,在Seed方法。

protected override void Seed(Context context)
{
    // create the type 
    var sql = "if type_id('udt_period') is null create type udt_period from varchar(8) not null";
    context.Database.ExecuteSqlCommand(sql);
    // you can alter the table column type
    var alter = "alter table Degrees alter column {0} udt_period not null"
    context.Database.ExecuteSqlCommand(string.Format(alter,"StartOn"));
    context.Database.ExecuteSqlCommand(string.Format(alter,"EndOn"));
}

希望对你有帮助

你想做的是不可能的,EntityFramework不能映射3个属性的对象到一个列,你必须在StartOnEndOn的数据库中扩展3个属性到3列