Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
314 views
in Technique[技术] by (71.8m points)

c# - Entity Framework maps data wrong when the identity column is not unique

Without getting into the "why", just understand this in inherited and what I have to work with :)

I have an EF6 edmx mapped to a view. There is no identifying column on it, so in order for EF to map the entity, the first not-null column was selected as the PK. The original thought behind this was it is read only no updates or deletes would be done. There is no filtering (ODATA sits on top of this), and the only - and I mean only - way this is used is select top N * from the entity.

There are 4 records in the view.

TypeCode | Contact | UserID | LocaleID | EntityName
---------------------------------------------------------
1          6623      1032     9          Jane
1          6623      1032     9          Jane
1          6623      1032     9          John
1          6623      1032     9          John

The problem I am seeing is that EF is mapping all 4 rows the same. All "John" names above become "Jane"

OK, putting aside the design decision, and the fact there is no identifying record on the view, why is EF mapping the last two rows wrong? My initial thought is that since the "PK" is set as TypeCode It doesn't know how to do it. But why would it be using the key column when just reading results from the database? I would have thought it only mattered for updates and deletes

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you query data by Entity Framework, the default behavior is that each materialized entity is tracked by its unique key. The unique key consists of any properties you told EF to use as key, or, alternatively, it inferred as key properties (TypeCode in your case). Whenever a duplicate entity key tries to enter the change tracker, an error is thrown telling that the object is already being tracked.

So EF simply can't materialize objects having duplicate primary key values. It would compromise its tracking mechanism.

It appears that, at least in EF6, AsNoTracking() can be used as a work-around. AsNoTracking tells EF to just materialize objects without tracking them, so it doesn't generate entity keys.

What I don't understand is why EF doesn't throw an exception whenever it reads duplicate primary key values. Now it silently returns the same object as many times as it encounters its key value in the SQL query result. This has caused many many people to get confused to no end.

By the way, a common way to avoid this issue is by generating temporary unique key values to the view by using ROW_NUMBER in Sql Server. That's good enough for read-only data that you read once into one context instance.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...