使用Entity Framework设置SQL列的默认值

25 浏览
0 Comments

使用Entity Framework设置SQL列的默认值

我正在尝试使用Code-First EF6与默认的SQL值。\n例如,我有一个\"CreatedDate\"列/属性,非空,在SQL中具有默认值\"getdate()\"\n我如何在我的代码模型中表示这个?目前我有:\n\nPublic Property CreatedDate As DateTime\n\n这样会起作用吗,或者我需要使用可空类型,即使实际列应该是非空的,这样当EF没有设置值时,它不会发送一个值:\n\nPublic Property CreatedDate As DateTime?\n\n还是有更好的解决方案?\n我不想让EF处理我的默认值 - 我知道这对我是可用的,但在我的当前情况下不可能。

0
0 Comments

问题出现的原因:

该代码是为了解决在使用Entity Framework与MySQL数据库时,实体类的属性无法获取到默认值的问题。在MySQL中,可以为列设置默认值,但是在Entity Framework中,通过读取实体类的属性时无法获取到这些默认值。因此,该代码通过查询information_schema.columns表来获取列的默认值,并将其设置到对应的实体属性或字段上。

解决方法:

该代码是一个扩展方法,可以将其添加到数据库的部分类中。它的作用是获取实体类对应的数据库表的列的默认值,并将这些默认值设置到实体类的属性或字段上。

具体实现步骤如下:

1. 获取实体类对应的表名。

2. 构造查询语句,查询information_schema.columns表,获取列名和默认值。

3. 使用Entity Framework的Database.SqlQuery方法执行查询语句,将查询结果转换为列表。

4. 遍历查询结果,对于每个列,默认值分别设置到实体类的属性或字段上。

代码中的DBDefaults类用于存储查询结果的列名和默认值。

文章内容如下:

在使用Entity Framework与MySQL数据库时,我们可能会遇到一个问题:无法获取到实体类属性的默认值。在MySQL中,可以为列设置默认值,但是在Entity Framework中,通过读取实体类的属性时无法获取到这些默认值。为了解决这个问题,我们可以使用下面的代码:

public static bool GetDBDefaults(object entity)
{
    try
    {
        string table_name = entity.GetType().Name;
        string q = $"select column_name, column_default from information_schema.columns where column_default is not null and table_schema not in ('information_schema', 'sys', 'performance_schema', 'mysql') and table_name = '{table_name}' order by table_schema, table_name, ordinal_position;";
        List dbDefaults = new List();
        using (DatabaseModelFull db = new DatabaseModelFull())
        {
            dbDefaults = db.Database.SqlQuery(q).ToList();
        }
        Type myType = entity.GetType();
        IList props = new List(myType.GetProperties());
        IList fields = new List(myType.GetFields());
        foreach (var dbDefault in dbDefaults)
        {
            var prop = props.SingleOrDefault(x => x.Name == dbDefault.column_name);
            if (prop != null)
            {
                if (dbDefault.column_default.Equals("CURRENT_TIMESTAMP"))
                    prop.SetValue(entity, System.Convert.ChangeType(DateTime.Now, prop.PropertyType));
                else
                    prop.SetValue(entity, System.Convert.ChangeType(dbDefault.column_default, prop.PropertyType));
                continue;
            }
            var field = fields.SingleOrDefault(x => x.Name == dbDefault.column_name);
            if (field != null)
            {
                if (dbDefault.column_default.Equals("CURRENT_TIMESTAMP"))
                    field.SetValue(entity, System.Convert.ChangeType(DateTime.Now, field.FieldType));
                else
                    field.SetValue(entity, System.Convert.ChangeType(dbDefault.column_default, field.FieldType));
            }
        }
        return true;
    }
    catch
    {
        return false;
    }
}
public class DBDefaults
{
    public string column_name { get; set; }
    public string column_default { get; set; }
}

以上代码是一个扩展方法,可以将其添加到数据库的部分类中。它通过查询information_schema.columns表来获取列的默认值,并将其设置到对应的实体属性或字段上。

使用该方法可以解决实体类属性无法获取到默认值的问题,提供了一种简单的解决方案。

请注意,由于访问了database_schema,该方法可能不是最快的,并且需要确保实体类与表名相同(或者进行相应的修改)。

希望以上内容对大家有所帮助。

0
0 Comments

在Entity Framework中,设置SQL列的默认值可能会出现问题。下面是一个关于如何解决这个问题的答案,同时还提到了使用EF Core的解决方法。

在EF6中,可以使用Fluent API的HasDefaultValue方法来设置默认值。下面是一个示例代码:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity()
        .Property(b => b.Rating)
        .HasDefaultValue(3);
}

如果需要设置NULL值作为默认值,可以使用HasDefaultValueSql方法:

.HasDefaultValueSql("NULL");

此外,还可以使用Migrations的Up和Down方法来修改默认值。需要注意的是,在修改默认值之前可能需要先删除索引。以下是一个示例代码:

public partial class RemovingDefaultToZeroPlantIdManualChange : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropIndex(
            name: "IX_TABLE_NAME_COLUMN_NAME",
            table: "TABLE_NAME"
        );
        migrationBuilder.AlterColumn(
            name: "COLUMN_NAME",
            table: "TABLE_NAME",
            nullable: true,
            //在Up方法中,指定一个新的defaultValue:
            defaultValueSql: "NULL",
            oldClrType: typeof(int));
        migrationBuilder.CreateIndex(
            name: "IX_TABLE_NAME_COLUMN_NAME",
            table: "TABLE_NAME",
            column: "COLUMN_NAME"
        );
    }
    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropIndex(
            name: "IX_TABLE_NAME_COLUMN_NAME",
            table: "TABLE_NAME"
        );
        migrationBuilder.AlterColumn(
            name: "COLUMN_NAME",
            table: "TABLE_NAME",
            nullable: true,
            //在Down方法中,将defaultValue恢复为旧值:
            defaultValueSql: "0",
            oldClrType: typeof(int));
        migrationBuilder.CreateIndex(
            name: "IX_TABLE_NAME_COLUMN_NAME",
            table: "TABLE_NAME",
            column: "COLUMN_NAME"
        );
    }
}

总结起来,使用Fluent API的HasDefaultValue方法可以设置SQL列的默认值,在EF Core中可以使用HasDefaultValueSql方法。此外,还可以使用Migrations的Up和Down方法来修改默认值。

0
0 Comments

问题的原因是在EF6中没有一个属性来定义用于某个属性默认值的数据库函数。解决方法是使用Computed属性和Migrations来指定默认的数据库函数。你可以运行一个迁移并手动修改它以包含默认的SQL函数。

首先,在你的C#类中定义一个计算属性,不需要可为空。然后运行迁移并手动修改它以包含默认的SQL函数。迁移的代码如下:

public partial class Initial : DbMigration
{
    public override void Up()
    {
        CreateTable(
            "dbo.MyEntities",
            c => new
                {
                    Id = c.Int(nullable: false, identity: true),
                    Name = c.String(),
                    Created = c.DateTime(nullable: false, defaultValueSql: "GetDate()"),
                })
            .PrimaryKey(t => t.Id);
    }
    
    public override void Down()
    {
        DropTable("dbo.MyEntities");
    }
}

在迁移代码中,你会注意到defaultValueSql函数。这是使计算工作的关键。

0