在我们的项目中,我们需要向DB添加一些预定义的数据。我认为最好的方法和概念是用于EF迁移(不是种子方法)。
但是我们在向DB添加相关数据方面遇到了很大的麻烦:
例如:
假设我们有2个表:
用户:
角色:
我们假设我们需要添加User(Name ='John',RoleId =(名称为'Admin'的角色的ID)。)
我们怎么做?如果我们找到一个允许我们执行不使用Code First实体的纯SQL SELECT脚本的解决方案,那将是很好的,因为它们可以被修改或删除。
对于 DELETE , INSERT , UPDATE 可以使用 Sql (...)方法但是怎么样?的 选择
答案 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