加入收藏 | 设为首页 | 会员中心 | 我要投稿 湖南网 (https://www.hunanwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

entity-framework – 实体框架6:怎样包围SQL天生器?

发布时间:2021-03-14 16:31:44 所属栏目:编程 来源:网络整理
导读:我想在天生数据库模式(DDL)时修改由EF:CF天生的SQL,如 suggested by the Entity Framework team. 怎样才气做到这一点? 我无法通过Google找到吻合的内容. 办理要领 您可以通过挪用DbMigrationsConfiguration类的结构函数中的 DbMigrationsConfiguration.SetS
副问题[/!--empirenews.page--]

我想在天生数据库模式(DDL)时修改由EF:CF天生的SQL,如 suggested by the Entity Framework team.

怎样才气做到这一点?

我无法通过Google找到吻合的内容.

办理要领

您可以通过挪用DbMigrationsConfiguration类的结构函数中的 DbMigrationsConfiguration.SetSqlGenerator()要领,转达数据库提供措施名称(譬喻,SQL Server的“System.Data.SqlClient”)以及要用于的MigrationSqlGenerator实例来包围Entity Framework行使的 MigrationSqlGenerator.该数据库提供者.

思量您链接到的the work item中的示例:

public class MyEntity
{
    public int Id { get; set; }

    [Required]
    [MinLength(5)]
    public string Name { get; set; }
}

假设已天生MyEntity表,并行使Add-Migration呼吁添加Name字段.

默认环境下,scaffolded迁徙是:

public partial class AddMyEntity_Name : DbMigration
{
    public override void Up()
    {
        AddColumn("dbo.MyEntity","Name",c => c.String(nullable: false));
    }

    public override void Down()
    {
        DropColumn("dbo.MyEntity","Name");
    }
}

请留意,脚手架没有为MinLengthAttribute天生任何内容.

要使EF通报最小长度要求,您可以行使specify an attribute-to-column annotation convention.如该文档页面所述,默认SQL天生器会忽略任何AnnotationValues.

在DbContext的OnModelCreating()包围中,添加以下内容:

modelBuilder.Conventions.Add(new AttributeToColumnAnnotationConvention<MinLengthAttribute,Int32>("minLength",(property,attributes) => attributes.Single().Length));

添加之后,您可以通过运行Add-Migration -Force AddMyEntity_Name从头天生scaffolded迁徙.此刻脚手架迁徙是:

public partial class AddMyEntity_Name : DbMigration
{
    public override void Up()
    {
        AddColumn("dbo.MyEntity",c => c.String(nullable: false,annotations: new Dictionary<string,AnnotationValues>
            {
                { 
                    "minLength",new AnnotationValues(oldValue: null,newValue: "5")
                },}));
    }

    public override void Down()
    {
        DropColumn("dbo.MyEntity",removedAnnotations: new Dictionary<string,object>
            {
                { "minLength","5" },});
    }
}

假设,如在链接的事变项中,您要天生束缚以搜查修剪的Name值是否大于minLength(在本例中为5).

您可以起首建设一个自界说MigrationSqlGenerator,它扩展SqlServerMigrationSqlGenerator并挪用SetSqlGenerator()来安装自界说MigrationSqlGenerator:

internal class CustomSqlServerMigrationSqlGenerator : SqlServerMigrationSqlGenerator
{
    protected override void Generate(AddColumnOperation addColumnOperation)
    {
        base.Generate(addColumnOperation);
    }
}

internal sealed class Configuration : DbMigrationsConfiguration<DataContext>
{
    public Configuration()
    {
        AutomaticMigrationsEnabled = false;

        SetSqlGenerator("System.Data.SqlClient",new CustomSqlServerMigrationSqlGenerator());
    }

    protected override void Seed(DataContext context)
    {
        //...
    }
}

此刻,此CustomSqlServerMigrationSqlGenerator会包围Generate(AddColumnOperation)要领,但只需挪用根基实现.

假如你看一下the documentation of AddColumnOperation,你会看到两个重要的属性,Column和Table.列是由up()中的lambda建设的ColumnModel,c => c.String(nullable:false,annotations:…).

在Generate()要领中,您可以通过ColumnModel的Annotations属性会见自界说AnnotationValues.

要天生添加束缚的DDL,您必要天生SQL并挪用Statement()要领.譬喻:

internal class CustomSqlServerMigrationSqlGenerator : SqlServerMigrationSqlGenerator
{
    protected override void Generate(AddColumnOperation addColumnOperation)
    {
        base.Generate(addColumnOperation);

        var column = addColumnOperation.Column;
        if (column.Type == System.Data.Entity.Core.Metadata.Edm.PrimitiveTypeKind.String)
        {
            var annotations = column.Annotations;
            AnnotationValues minLengthValues;
            if (annotations.TryGetValue("minLength",out minLengthValues))
            {
                var minLength = Convert.ToInt32(minLengthValues.NewValue);
                if (minLength > 0)
                {
                    if (Convert.ToString(column.DefaultValue).Trim().Length < minLength)
                    {
                        throw new ArgumentException(String.Format("minLength {0} specified for {1}.{2},but the default value,'{3}',does not satisfy this requirement.",minLength,addColumnOperation.Table,column.Name,column.DefaultValue));
                    }

                    using (var writer = new StringWriter())
                    {
                        writer.Write("ALTER TABLE ");
                        writer.Write(Name(addColumnOperation.Table));
                        writer.Write(" ADD CONSTRAINT ");
                        writer.Write(Quote("ML_" + addColumnOperation.Table + "_" + column.Name));
                        writer.Write(" CHECK (LEN(LTRIM(RTRIM({0}))) > {1})",Quote(column.Name),minLength);
                        Statement(writer.ToString());
                    }
                }
            }
        }
    }
}

(编辑:湖南网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读