简体   繁体   中英

Entity Framework oddity - one column is wrong

First off, I already have a workaround, plus the database this is happening on is being replaced (completely new db / schema + new app)

That being said, I'd like to understand WHY this happened so I don't run into it again. Thoughts are appreciated.

Anyways: take this simple line of code:

var privs = _olddb.tbl_Privileges.Where(x => x.UserID == userFrom);

Simple enough. Basically, an example of the data coming out should be:

+--------+----------+------------+----------------+------------+
| UserID | RegionID | FacilityID | InitiativeType | AccessType |
+--------+----------+------------+----------------+------------+
|    290 |       27 |        123 | C              | F          |
|    290 |       27 |        123 | P              | F          |
|    290 |       27 |        124 | C              | F          |
|    290 |       27 |        124 | P              | F          |
+--------+----------+------------+----------------+------------+

Instead though... I get this:

+--------+----------+------------+----------------+------------+
| UserID | RegionID | FacilityID | InitiativeType | AccessType |
+--------+----------+------------+----------------+------------+
|    290 |       27 |        123 | P              | F          |
|    290 |       27 |        123 | P              | F          |
|    290 |       27 |        124 | P              | F          |
|    290 |       27 |        124 | P              | F          |
+--------+----------+------------+----------------+------------+

Note the InitiativeType column....

However, if I run this command:

var privs =_olddb.Database.SqlQuery<tbl_Privileges>("SELECT * FROM tbl_Privileges WHERE UserID = " + userFrom);

Then I get the correct output.

What gives?

-EDIT- Regarding answer provided by marc_s (Keep in mind, I had no hand in making the original db, and I'm afraid to modify it, it's in use by a very old web app..) I honestly feel silly for not having checked the PK's before posting, my apologies. I checked the database, that table has no PK's defined at all. So I checked the edmx in EF, and found only RegionID and FacilityID were set a Entity Keys:

在此输入图像描述

So I updated the edmx model and set all fields as keys (since I can have 4 fields the same easily between two privilege sets, as Access Type has multiple values as well), ran the script again, and this time it worked perfectly with the Linq statement.

Most likely , it's a problem with the definition of your primary key on the source table - I've seen this happen when querying views (which don't have a pre-defined primary key, typically).

Assume your PK on that table is ( UserID, RegionID, FacilityID ) (just my guess, since they're all called ..ID - could be wrong). When you get 4 rows back from SQL Server, the first row contains the values ( 290, 27, 123 ) as the primary key; EF happily creates an instance of your object with those values (and the other non-key columns) for you.

Now comes the second row - again, the PK values are ( 290, 27, 123 ), and now EF goes hmmmm, I've seen those values before - this must be the same row again since the primary key by definition must be unique! So therefore, EF will add a second copy of that first object instance it's created.

So what you need to make sure is that your primary key - actually defined in the database on a table, or what EF assumes is the primary key for a view (by default: all non-nullable columns) is really unique for each row - otherwise you'll see things like this happening....

This will not happen with your second approach, where you basically just execute an arbitrary SQL statement - in this case, EF will map each row returned individually, without checking it's own primary key definition (since you're not really going through your DbContext and its model of the database)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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