简体   繁体   English

查看和实体框架数据不对?

[英]View and Entity Framework data not right?

I have a view from some table when I select from the view in SQL Server Management Studio it works fine, but when I use Entity Framework to get the data from view it's different. 当我从SQL Server Management Studio中的视图中选择它时,我有一个表的视图,它工作正常,但是当我使用Entity Framework从视图中获取数据时,它是不同的。

ReturnDbForTesEntities1 db = new ReturnDbForTesEntities1();
List<VJOBS2> list = new List<VJOBS2>();
list = db.VJOBS2.ToList();

Same number of records but last 2 rows are different. 相同数量的记录但最后2行是不同的。

I have table for job applicant applicant can apply for 2 jobs or more 我有求职者申请表可以申请2个或更多的工作

ApplicantId    ApplicantName  JobId  JobName
   1              Mohamed       1    Developer
   1              Mohamed       2    IT Supporter 

but in list 但在列表中

ApplicantId    ApplicantName  JobId  JobName
   1              Mohamed       1    Developer
   1              Mohamed       1    Developer

There is a subtle problem with views when used from Entity Framework. 从Entity Framework使用时, 视图存在一个微妙的问题。

If you have a table, do use it with EF, you need to have a primary key to uniquely identify each row. 如果您有一个表,请将它与EF一起使用,您需要有一个主键来唯一标识每一行。 Typically, that's a single column, eg an ID or something like that. 通常,这是一个列,例如ID或类似的东西。

With a view, you don't have the concept of a "primary key" - the view just contains some columns from some tables. 有了视图,您没有“主键”的概念 - 视图只包含某些表中的某些列。

So when EF maps a view, it cannot find a primary key - and therefore, it will use all non-nullable columns from the view as "substitute" primary key. 因此,当EF映射视图时,它无法找到主键 - 因此,它将使用视图中的所有非可空列作为“替换”主键。

I don't know what these are in your case - you should be able to tell from the .edmx model. 我不知道你的情况是什么 - 你应该能够从.edmx模型中得知。

Let's assume that (ApplicantId, ApplicantName) are the two non-nullable columns that EF now uses as a "substitute" primary key. 假设(ApplicantId, ApplicantName)是EF现在用作“替代”主键的两个不可为空的列。 When EF goes to read the data, it will read the first line (1, Mohamed, 1, Developer) and create an object for that. 当EF去读取数据时,它将读取第一行(1, Mohamed, 1, Developer)并为其创建一个对象。

When EF reads the second line (1, Mohamed, 2, IT-Supporter) , it notices that the "primary key" (1, Mohamed) is the same as before - so it doesn't bother creating a new object with those values read, but the primary key is the same, it hence must be the same object as it has already read before, so it uses that object instead. 当EF读取第二行(1, Mohamed, 2, IT-Supporter) ,它注意到“主键” (1, Mohamed)与之前相同 - 因此它不会打扰使用这些值创建新对象read,但主键是相同的,因此它必须是与之前已读过的相同的对象,因此它使用该对象。

So the problem really is that you can't have explicit primary keys on a view. 所以问题实际上是你不能在视图上有明确的主键。

Either you can tweak your EF model to make it clear to EF that eg (ApplicantId, JobId) is really the primary key (you need to make sure those columns are both non-nullable ) - or you need to add something like a "artificial" primary key to your view: 要么你可以调整你的EF模型,以使EF清楚,例如(ApplicantId, JobId)确实是主键(你需要确保这些列都是非可空的 ) - 或者你需要添加类似“人工”的​​东西“您的观点的主要关键:

CREATE VIEW dbo.VJOBS2
AS
   SELECT 
       ApplicantId, ApplicantName, JobId, JobName,
       RowNum = ROW_NUMBER() OVER(ORDER BY JobId)
   FROM
       dbo.YourBaseTable

By adding this RowNum column to your view, which just numbers the rows 1, 2, ...., n , you get a new, non-nullable column which EF will include into the "substitute PK" and since those numbers are sequential, no two rows will have the same "PK" values and therefore none will erroneously be replaced by something that's been read from the database already. 通过将此RowNum列添加到您的视图(仅对行1, 2, ...., n ,您将获得一个新的,不可为空的列,EF将包含在“替代PK”中,因为这些数字是顺序的,没有两行具有相同的“PK”值,因此没有一行会被已经从数据库中读取的内容错误地替换。

FYI, I had to add ISNULL to get it to work for me, see the modification in the first line of this code example: 仅供参考,我必须添加ISNULL以使其适用于我,请参阅此代码示例第一行中的修改:

SELECT ISNULL(ROW_NUMBER() OVER(ORDER BY a.OrderItemID),0) as ident, a.* 
FROM
(
      SELECT e.AssignedMachineID, e.StartDate, e.OrderItemID, e2.OrderItemID AS doubleBookedEventID, e.StartTime, e.EndTime, e2.StartTime AS doubleBookedStartDateTime, e2.EndTime AS doubleBookedEndDateTime, DATEDIFF(MINUTE,e2.StartTime,e.EndTime) AS doubleBookedMinutes
  FROM schedule e
    INNER JOIN schedule e2
      ON e.AssignedMachineID = e2.AssignedMachineID
      and e.StartDate=e2.StartDate
      AND e.schedID <> e2.schedID
      AND e2.StartTime BETWEEN DATEADD(minute,1,e.StartTime) AND DateAdd(minute,-1,e.EndTime) where  Coalesce(e.ManuallyOverrided,0)=0 and Coalesce(e.AssignedMachineID,0) > 0
      ) a

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM