【问题标题】:Read database during an entity framework migration (select query)在实体框架迁移期间读取数据库(选择查询)
【发布时间】:2016-07-27 21:51:27
【问题描述】:

我知道我可以在迁移期间使用Sql 方法更新数据,它非常适合可以用纯 SQL 表达的简单事物。

我也知道我可以使用 Seed 方法,但这感觉像是一种 hack(我要编写的代码必须在执行迁移时执行一次)。

在我目前的情况下,我需要从列中去除 HTML 标记,并将其写入迁移中添加的新列。我已经有一个 C# 方法可以做到这一点。我想要做的是遍历 C# 中的每一行,并为每一行生成一个 SQL 语句,该语句将使用相应的 HTML 剥离文本更新该行。

更一般地说,我认为在迁移过程中能够在 C# 中读取数据库在很多情况下都很方便。在迁移事务中这样做是完美的,但为此我需要检索 Entity Framework 内部用于迁移的 SQL 连接。

到目前为止,我还没有找到执行返回结果的 SQL 查询的方法。这可能吗?

【问题讨论】:

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


    【解决方案1】:

    我也更喜欢通过 Seed 方法转换迁移文件中的数据。

    更新数据应该没问题,你可以按照下面的代码行,你也可以在SQL字符串中从C#传递参数:

    Sql("UPDATE TableName SET MyValueInMinutes= -DATEDIFF(MINUTE, CurrentTime, 0)";
    

    数据读取的问题!实际上,您永远不需要在 C# 中处理数据转换,通常您在 SQL Server 中创建所有内容(存储过程和函数以及 SQL 语句),并且您可以在需要它们的时间点或何时从迁移文件中调用它们数据已准备好进行转换。但我认为您不是数据库程序员,这就是您尝试用 C# 处理数据的原因。

    这是一个如何遍历行的示例,我将搜索给定的文本并为您找到一个免费可用的“AnyText”+计数器。

    CREATE PROCEDURE sp_FindFreeName  
    @toBeFindName nvarchar(MAX) OUT  
    AS 
    BEGIN 
    DECLARE @LoopCounter INTEGER 
    SET @LoopCounter = 1 
    WHILE EXISTS (SELECT @toBeFindName FROM dbo.MyTable WHERE Name = @toBeFindName) 
      BEGIN 
          SET   @toBeFindName = 'AnyText', @LoopCounter) 
          SET @LoopCounter = @LoopCounter + 1 
      END 
    END 
    

    然后就可以调用form C#了:

    var cSharpName = string.Empty;
    Sql("exec sp_FindFreeName @toBeFindName=@"+ cSharpName +" OUTPUT");
    

    其中 cSharpName 由 C# 给出。

    第三个为什么要这样做,您也可以编写自己的 Code First 迁移操作。您必须按照 Rowan 博客中的说明定义 SqlServerMigrationSqlGenerator:

    https://romiller.com/2013/02/27/ef6-writing-your-own-code-first-migration-operations/

    结论:

    如果您真的想读取迁移文件中的数据,那么您必须使用例如:SqlDataReader 并且您还必须从 App.config 中读取连接字符串。

    在大多数用例中,您可以在 SQL Server 中执行所有操作。只需创建您的数据转换 SQL 脚本并从所需位置执行它们。

    您可以使用 Extensions 和 SqlServerMigrationSqlGenerator 以比 DataReader 更简洁的方式执行此操作。

    【讨论】:

    • 感谢您的回答。正如您所猜到的,我对 SQL 不太满意(我的同事也不是),而且,我想我可以用 SQL 编写整个网站,但我们选择了 C#,因为它更方便除了简单的数据库查询(例如解析 HTML,包括格式错误的 HTML)之外的任何内容的语言。我来看看迁移Operations,但乍一看,它们也不提供数据库连接(你可以盲目地导出SQL字符串吗?)。如果可能,我想避免创建与数据库的不同连接/事务。
    • @youen 然后使用种子方法进行迁移。在每个迁移级别迁移期间,种子方法将被调用 X 次。使用 If esle ... 来查找您当前工作的级别,然后您可以像往常一样在 C# 中使用非常简单的方法来添加、删除或更新数据。如果这能解决您的问题,请不要忘记投票并给出答案^^
    • @youen 有一件事仍然很重要,有 2 种 Seed 方法,一种用于 Init,一种用于 Migration。使用迁移种子,请阅读本文blog.oneunicorn.com/2013/05/28/…
    • 感谢您的精确,我不知道有两个 Seed 方法。但是,如果我理解正确,没有Seed 特定于一个迁移的方法,它会在执行迁移之后(以及下一次迁移之前)运行一次。那肯定会很有用,并且可以解决我当前的问题,但是那样行不通,不是吗?即使这样做了,它仍然会受到限制,因为有时需要在架构更改中交错数据初始化(例如,在创建列之后填充列,但在对其设置唯一索引之前)。
    • 由于没有人提供更好的答案,我接受了这个;特别是对于这一部分:“您必须使用 SqlDataReader 并且还必须从 App.config 中读取连接字符串”。这似乎是我的具体问题的唯一答案,即使它确实不是一个好方法。
    猜你喜欢
    • 2014-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-24
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多