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

时间:2014-02-15 15:09:58

标签: 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 (...)方法但是怎么样?的 选择

2 个答案:

答案 0 :(得分: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')).

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

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

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

答案 1 :(得分:2)

我正在使用旧的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();

        ...
    }
}

使用LINQ更好,即使是通常的迁移,因为DbMigration.Sql方法中存在一个错误,它会忽略参数:How to pass parameters to DbMigration.Sql() Method