我有一个包含视图的SQL Server数据库。
执行此查询时:
select *
from HistoryListingView
order by RequestTime desc`
我得到了这个结果:
但是,在我的控制器中(在ASP.NET MVC应用程序中),我只执行此代码:
return Ok(_db.HistoryListingViews.OrderByDescending(r => r.RequestTime));
收到的数据不符合;更准确地说,第{2}和第4行中的DataType
列不正确,其他所有列似乎都是正确的。
[
{
"dataType":"Type de stationnement",
"actionType":"Obtenir plusieurs entrées",
"requestTime":"2017-10-26T23:06:43.81",
"username":"admin",
"jsonParameters":"[]",
"error":null,
"userSessionRequestErrorId":null
},
{
"dataType":"Type de stationnement",
"actionType":"Obtenir plusieurs entrées",
"requestTime":"2017-10-26T23:06:43.81",
"username":"admin",
"jsonParameters":"[]",
"error":null,
"userSessionRequestErrorId":null
},
{
"dataType":"Local",
"actionType":"Obtenir plusieurs entrées",
"requestTime":"2017-10-26T23:06:42.687",
"username":"admin",
"jsonParameters":"[]",
"error":null,
"userSessionRequestErrorId":null
},
{
"dataType":"Local",
"actionType":"Obtenir plusieurs entrées",
"requestTime":"2017-10-26T23:06:42.687",
"username":"admin",
"jsonParameters":"[]",
"error":null,
"userSessionRequestErrorId":null
}
]
我的上下文配置了禁用的lazyLoading和禁用的ProxyCreation,而我的JsonFormatter(Newtonsoft)正在使用基本设置:
CamelCasePropertyNamesContractResolver
和
ReferenceLoopHandling.Ignore
我看不出有什么可以改变数据。有没有类似记录循环才能获得更好的性能?
答案 0 :(得分:4)
从Entity Framework使用时,视图存在一个微妙的问题。
如果您有桌子,请将其与EF一起使用,您需要使用主键来唯一标识每一行。通常,这是一个列,例如ID
或类似的东西。
使用视图,您没有“主键”的概念 - 视图只包含某些表中的某些列。
因此,当EF映射视图时,它无法找到主键 - 因此,它将使用视图中的所有不可为空的列作为“替换”主键。
我不知道你的情况是什么 - 你应该能够从.edmx
模型或从数据库生成的代码类中判断出来。
查看您的数据,我认为RequestTime
是您视图中唯一不可为空的列。 EF现在假设这是这个视图的“替代”主键。当EF去读取数据时,它将读取第一行(“Type de stationnement”)并创建一个对象那个。
当EF读取第二行时,RequestTime
相同,因此替代“主键”(RequestTime
)与以前相同 - 所以它不会打扰创建一个读取了这些值的新对象,但是主键是相同的,因此它必须是与之前已读过的对象相同的对象,因此它使用该对象。
所以问题实际上是你不能在视图上有明确的主键。
你可以调整你的EF模型,使EF清楚主键是什么(你需要确保这些列是不可空的) - 或者你需要添加类似的东西您的观点的“人为”主键:
CREATE VIEW dbo.HistoryListingView
AS
SELECT
(all the columns you already have in your view),
RowNum = ROW_NUMBER() OVER(ORDER BY SomeValue)
FROM
dbo.YourBaseTable
通过将此RowNum
列添加到您的视图(仅对行1,2,...,n进行编号),您将获得一个新的,不可为空的列,EF将包含在“替代PK”中“并且由于这些数字是连续的,因此没有两行具有相同的”PK“值,因此没有任何行将被错误地替换为已经从数据库中读取的数据。
答案 1 :(得分:0)
感谢@marc_s的回答,但
这对我不起作用,因为RowNum
仍然可以为空
但是,当我添加ISNULL(ROW_NUMBER() OVER(ORDER BY SomeValue))
时