I'm trying to figure out why a simple query in LINQ is returning odd results.
I have a view defined in the database. It basically brings together several other tables and does some data munging. It really isn't anything special except for the fact that it deals with a large data set and can be a bit slow.
I want to query this view based on a long. Two sample queries below show different queries to this view.
var la = Runtime.OmsEntityContext.Positions.Where(p => p.AccountNumber == 12345678).ToList();
var deDa = Runtime.OmsEntityContext.Positions.Where(p => p.AccountNumber == 12345678).Select(p => new { p.AccountNumber, p.SecurityNumber, p.CUSIP }).ToList();
The first one should hand back a List. The second one will be a list of anonymous objects.
When I do these queries in entities framework the first one will hand me back a list of results where they're all exactly the same.
The second query will hand me back data where the account number is the one that I queried and the other values differ. This seems to do this on a per account number basis, ie if I were to query for one account number or another all the Position objects for one account would have the same value (the first one in the list of Positions for that account) and the second account would have a set of Position objects that all had the same value (again, the first one in it's list of Position objects).
I can write SQL that is in effect the same as either of the two EF queries. They both come back with results (say four) that show the correct data, one account number with different securities numbers.
Why does this happen??? Is there something that I could be doing wrong so that if I had four results for the first query above that the first record's data also appears in the 2-4th's objects???
I cannot fathom what would/could be causing this. I've searched Google for all kinds of keywords and haven't seen anyone with this issue. We partial class out the Positions class for added functionality (smart object) and some smart properties. There are even some constructors that provide some view model type support. None of this is invoked in the request (I'm 99% sure of this). However, we do this same pattern all over the app.
The only thing I can think of is that the mapping in the EDMX is screwy. Is there a way that this would happen if the "primary keys" in the EDMX were not in fact unique given the way the view is constructed? I'm thinking that the dev who imported this model into the EDMX let the designer aut开发者_JS百科o select what would be unique.
Any help would give a haggered dev some hope!
The answer to this particular issue is this:
MAKE SURE YOUR ENTITY KEYS ARE UNIQUE!!!
The view as it was generated in the EDMX has three columns/properties that were marked as entity keys (which I guess the combination of make a unique id for a record).
In my queries these three columns were all the same. I am assuming that the entity framework freaked out and just placed the first record into all the subsequent records till one of those columns changed (thus a new unique "set").
Now that I've figured that out I looked back at the place where this information was first being used and saw that a grouping statement was applied first (the data is being queried through a stored procedure in another place in the app). The group flattened out one of the entity key columns such that it was always unique. This causes the results in that location to appear fine.
My solution is to add a new column to this view that just projects a GUID (using NEWID() in SQL). The problem is I know don't know how to tell the EDMX to use this newly added property as the sole entity key for the mapped view!
-I'm closing this as fixed as I know what the problem and will be asking my other question in a new question. Thanks for all the insight for those who took the time to answer!
Have you tried this type of syntax? Can't imagine it's the cause, but who knows...
using (var dc = new OmsEntityContext())
{
var la = (from p in dc.Position
where p.AccountNumber = "12345678"
select p).ToList();
}
and
using (var dc = new OmsEntityContext())
{
var deDa = (from p in dc.Position
where p.AccountNumber = "12345678"
select new {p.AccountNumber, p.SecurityNumber, p.CUSIP}).ToList();
}
</longShot>
精彩评论