在我们的项目中,我们需要向DB添加一些预定义的数据.我认为最好的方法和概念是用于EF迁移(不是种子方法).
但是我们在向DB添加相关数据时遇到了很大的麻烦:
例如:
假设我们有2个表:
用户:
角色:
假设我们需要添加User(Name ='John',RoleId =(名称为'Admin'的角色的Id)).
我们怎么做?如果我们找到一个允许我们执行不使用Code First实体的纯SQL SELECT脚本的解决方案,那将是很好的,因为它们可以被修改或删除.
对于DELETE,INSERT,UPDATE可以使用Sql(...)方法但是SELECT怎么样?
您无法在迁移中使用上下文.
逻辑上首先运行迁移到更新数据库架构,然后您可以通过它来使用上下文来处理数据.如果您的数据库与模型不匹配,或者表格仍然不存在,则无法在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
我为此使用了很好的旧 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() 方法
| 归档时间: |
|
| 查看次数: |
6698 次 |
| 最近记录: |