EF 6迁移:如何执行sql SELECT?

pry*_*bov 8 entity-framework

在我们的项目中,我们需要向DB添加一些预定义的数据.我认为最好的方法和概念是用于EF迁移(不是种子方法).

但是我们在向DB添加相关数据时遇到了很大的麻烦:

例如:

假设我们有2个表:

用户:

  • Id(PK自动增量)
  • 名称
  • 角色ID

角色:

  • Id(PK自动增量)
  • 名称

假设我们需要添加User(Name ='John',RoleId =(名称为'Admin'的角色的Id)).

我们怎么做?如果我们找到一个允许我们执行不使用Code First实体的纯SQL SELECT脚本的解决方案,那将是很好的,因为它们可以被修改或删除.

对于DELETE,INSERT,UPDATE可以使用Sql(...)方法但是SELECT怎么样?

Vas*_*pov 7

您无法在迁移中使用上下文.

逻辑上首先运行迁移到更新数据库架构,然后您可以通过它来使用上下文来处理数据.如果您的数据库与模型不匹配,或者表格仍然不存在,则无法在EF中使用它.

我不得不查看EF代码(也因为好奇).下面几个级别的DbMigration类中的Sql()方法实际上只是将SQL字符串添加到应该在事务中执行并继续运行的查询列表中.它在调用时不会执行它.因此,简而言之,EF只需填写一列代码行,这些代码行应该立即执行.如果您尝试使用迁移代码中的C#代码可以处理的所有路径,这似乎是正确的.

问题实际上是相当不错的,遗憾的是我仍然没有找到任何更好的解决方案,而不是使用纯ADO.

另一个选择是生成更多自定义SQL查询,并更广泛地使用T-SQL.对于您想要插入用户并按名称设置groupId的情况,它可以与内部选择一起使用:

INSERT INTO Users (Name, GroupId)
VALUES ('John', RoleId = (SELECT Id FROM Roles WHERE Name = 'Admin')).
Run Code Online (Sandbox Code Playgroud)

对于我的问题,我不得不做一些更复杂的执行 - 以下与DbSet的AddOrUpdate方法相同,使用IF语句:

IF EXISTS (SELECT * FROM Table1 WHERE Column1='SomeValue')
    UPDATE Table1 SET (...) WHERE Column1='SomeValue'
ELSE
    INSERT INTO Table1 VALUES (...)
Run Code Online (Sandbox Code Playgroud)

我在这里找到了它:http://blogs.msdn.com/b/miah/archive/2008/02/17/sql-if-exists-update-else-insert.aspx


omi*_*kad 5

我为此使用了很好的旧 LINQ:

public override void Up()
{
    using (var dc = new DbContext("your connection string or name"))
    {
        var ids = dc.Database.SqlQuery<int>("SELECT id FROM sometable WHERE somefield={0}", 42).ToArray();

        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

使用 LINQ 更好,即使对于通常的迁移,因为 DbMigration.Sql 方法中有一个错误,它忽略参数:如何将参数传递给 DbMigration.Sql() 方法

  • 此答案的代码中没有 LINQ:只有 SQL。这很好:当它不是 LINQ 时,不要一直称它为 LINQ。 (7认同)