假设我有一个实体类A,它为其PK使用代理键,并定义了一个唯一性约束,它将FK引入另一个实体类B.一切都很好。但是,在某个地方,我发现我的实体类A实际上是由B的键列的子集定义的,而不是B的所有键列。
基本上,情况是:我想添加一些列,并使用旧列和关系中的现有数据计算的值填充它们,然后再删除旧列。
从表面上看,这看起来很简单 - 我对数据模型进行了更改,添加了新的迁移,然后在添加新的数据后使用调用Sql()和执行该数据运动所需的T-Sql列,在我们删除旧列之前。
但是,在我的查询中使用新列似乎会导致问题,可能是因为整个迁移都是以批处理或其他方式执行的。
在这个例子中,添加的新列是BName,它只是一个简单的练习,用B中的Name列填充它。在迁移执行之前,BName确实存在于A上。
UPDATE [dbo].[A] SET a.[BName] = b.[Name],
FROM [dbo].[A] a
FULL OUTER JOIN [dbo].[B] b ON a.[BId] = b.[Id]
这会产生:
System.Data.SqlClient.SqlException (0x80131904): The multi-part identifier "a.BName" could not be bound.
我已经尝试在我传递给Sql()的查询中使用GO命令分解批处理,但是在这个工具集中不支持它们。
System.Data.SqlClient.SqlException (0x80131904): Incorrect syntax near 'GO'.
考虑到EF的当前状态,最好的解决方法是什么?我四处搜索并发现了一些建议,即在单独的迁移中执行模式更改和数据运动,但我发现由于此更改的逻辑原子性,这是不合适的。也许我可以与EF进行足够的斗争以同时开发两个单独的迁移,以便我可以同时将它们检查到源代码控制中,但是为了仅仅为了组织起见,我想要做很多不必要的痛苦。
编辑:对于它的价值,the documentation on EFCF Migrations似乎表明这是支持的。然而我的仍然破碎。但是,我充满希望,这只是我的一个愚蠢的错误,而不是框架的缺点。
答案 0 :(得分:2)
看起来这可能只是上述查询的语法问题。我稍微改了一下,这似乎有效:
UPDATE [dbo].[A] SET [BName] = [B].[BName]
FROM [dbo].[A]
FULL OUTER JOIN [dbo].[B] ON [A].[BId] = [B].[Id]
我不知道为什么这会有所作为,虽然直接使用这样的表名感觉很奇怪,但是我可以以把它放到床上的名义做出让步。