EntityFramework拒绝忘记旧列

Nac*_*ica 5 c# entity-framework ef-database-first entity-framework-6

我正在使用EntityFramework 6.1.3,数据库优先.我现在希望我选择代码优先...

我有一个包含一些表的数据库.我之前已经从这些表中构建了我的edmx.然后我改变了几列的类型并添加了几列.例如,将bit列更改为int列.

我尝试使用从数据库更新我的模型right-click -> Update Model from Database.

似乎无论我做什么,EF都只会像我创建edmx时那样获​​取数据库的状态.我尝试过的事情:

  1. 重新打开Visual Studio
  2. 重建项目
  3. 删除并重新添加实体(这是大多数人认为应该工作的)
  4. 在Visual Studio关闭并替换它们时,在整个项目中搜索xml或C#中的文本引用到我的列.(这似乎最初起作用,但如果我再次尝试从数据库更新它会写入它们)
  5. 重新启动SQL服务
  6. 重启机器
  7. 所有.tt文件上的"运行自定义工具"(不应该有所作为但是到底是什么)

当我右键单击我的实体并选择"表映射"时,它始终显示bit左侧的旧列.

映射问题

这是我的数据库表设计:

sql表设计

可能需要注意的是,实体正在离开视图,而不是直接离开表格.但是当我正在调查这个问题时,视图实际上是表的select*,我已经确认了powershell,视图返回的类型是int:

PS> $conn = new-object data.sqlclient.SqlConnection("data source=localhost;initial catalog=dbname;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework")
PS> $conn.open()
PS> $query = $conn.createcommand()
PS> $query.commandtext = "select * from [dbname].[LocalCustom].[viewname]"
PS> $reader = $query.executereader()
PS> $reader.getschematable().rows[19]

ColumnName                      : ActiveMember
ColumnOrdinal                   : 19
ColumnSize                      : 4
NumericPrecision                : 10
NumericScale                    : 255
IsUnique                        : False
IsKey                           :
BaseServerName                  :
BaseCatalogName                 :
BaseColumnName                  : ActiveMember
BaseSchemaName                  :
BaseTableName                   :
DataType                        : System.Int32
AllowDBNull                     : False
ProviderType                    : 8
IsAliased                       :
IsExpression                    :
IsIdentity                      : False
IsAutoIncrement                 : False
IsRowVersion                    : False
IsHidden                        :
IsLong                          : False
IsReadOnly                      : False
ProviderSpecificDataType        : System.Data.SqlTypes.SqlInt32
DataTypeName                    : int
XmlSchemaCollectionDatabase     :
XmlSchemaCollectionOwningSchema :
XmlSchemaCollectionName         :
UdtAssemblyQualifiedName        :
NonVersionedProviderType        : 8
IsColumnSet                     : False
Run Code Online (Sandbox Code Playgroud)

我现在的主要问题是...... EF如何知道它曾经是一种bit类型?它存储这些数据在哪里?当然,我也想知道如何使用UI正确更新模型,而无需删除和重新添加实体或其他任何我必须做的事情才能让它更新.

我很沮丧EF :(

Tri*_*oan 9

这是我在使用Entity Framework数据库时经常遇到的情况.当您从数据库进行一些更改时,要更新EF,您应该:

  1. 删除.edmx中的修改表
  2. 将该表重新添加到.edmx中 right-click -> Update Model from Database -> check that table

  • 我已经试过了.它在我的名单上排名第3 (2认同)

xum*_*m59 5

好吧,即使没有更改,也只需编辑/更新您的视图。EF 不会更新未修改的项目。

只要您没有更改/更新视图而是基础表,EF 就无法检测到是否需要更改任何内容。我确实相信这种行为是为了防止每次都完全重建模型。


由于 OP 希望了解“为什么”,我进行了一些测试。

首先,我创建了一个表和一个“SELECT *”视图:

create table TableToChange(rowKey bigint IDENTITY(1,1) not null, myBitFlag bit null, myIntFlag int)
go
create view SelectStarOnChangingTable as SELECT * FROM TableToChange
go
Run Code Online (Sandbox Code Playgroud)

然后我对使用以下命令创建的 sys 对象和列进行了一些检查:

select * 
from sys.all_objects AO 
    join sys.all_columns AC on AC.object_id=AO.object_id
where AO.object_id in (--insert your objet_ids here--)
Run Code Online (Sandbox Code Playgroud)

对 table 对象做一些小的更改:

alter table TableToChange
drop column myBitFlag
go
alter table TableToChange
add myBitFlag int
go
Run Code Online (Sandbox Code Playgroud)

如果您再次运行架构查询,您会注意到更新的列在 USER_TABLE 行和 VIEW 行中没有相同的类型(56 对 104)

更改SelectStarOnChangingTable视图而不进行更改将强制 SQL Server 更新。

我们现在有一个罪魁祸首:SQL Server 存储视图的列类型,阻止 EF 更新其模型,即使实体是从头开始重建的。