数据库表结构变化引起视图字段类型推断错误

这几天,客户报告了一个Bug,  经过跟踪,发现是下面linq语句引起的,

manuLines = CustomerDBContext.Bookkeeping_Netvisor_PurchaseInvoicesLines.Where(Function(pil) pil.PIL_PI_SysID = sysID).ToList()

 

它会抛出一个转换异常: unable to cast object of type "System.Int32" to "System.String", 然后在堆栈里追踪到其中一步是 SqlDataReader.get_string()...

这个程序已经跑了很久,一直没有问题, Bookkeeping_Netvisor_PurchaseInvoicesLines 是一个视图, 我跟踪Runtime执行这句后生成的sql, 把它拿到查询分析器里执行,也没有问题,看了数据类型的匹配,还是没有问题, 百思不得其解! 

偶然, 我把视图删除了,用一样的语句重建,它又正常工作了, 于是我推断是数据库表结构变化,引起视图的结构推断问题。 我重新把数据库恢复到删除视图并重建前, 并调用 sp_refreshView 'Bookkeeping_Netvisor_PurchaseInvoicesLines' ,发现也能解决问题。  后来终于在微软 MSDN文章中找到正解:

http://msdn.microsoft.com/zh-cn/library/ms187821.aspx ,

大致意思是说:在创建视图时,如果没有用 with schemabinding 关键字

则视图相关联表结构的变化可能导致视图结构推断出错。 解决方案是一个个调用 sp_refreshView '视图名' 刷新相关联视图。

需要注意的是,如果要在视图上创建索引, 也需要在创建视图时使用with schemabinding 关键字,这个在百度知道里已经有人给出了答案,

 

在视图上创建索引是有一定的限制的。如楼主所说,要在视图上创建索引,视图定义的时候要包含WITH SCHEMABINDING选项,另外必须在视图上创建一个唯一聚集索引以后才可以创建非聚集索引。
写了个例子楼主看一下
CREATE TABLE dbo.Test(a int,b int)
GO
CREATE VIEW vTest WITH SCHEMABINDING
AS
SELECT a,b
FROM dbo.Test
GO
CREATE UNIQUE CLUSTERED INDEX IX_vTest_a ON vTest(a)
--注意,由于是唯一性索引,如果基表Test的a列包含重复值的话索引是不能创建成功的
GO
--再创建一个非聚集索引
CREATE INDEX IX_vTest_b ON vTest(b)

 

转载于:https://www.cnblogs.com/Hcsdn/archive/2013/02/19/2916712.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值