注意
这可能是this的重复。但我没有得到明确的答案。
问题
我从linq那里得到了错误的结果。
示例
id groupid status name
------------------------------------
guid1 guidA reserved truck1
guid2 guidA reserved truck2
guid3 guidA reserved truck3
guid4 guidA reserved truck4
*assume all guids are guids..
**id is a primary key (unique)
CASE
如果我只放where groupid == guidA
,结果是正确的(4行)
但是,如果我把where groupid == guidA && status == reserved
结果错了(3行)
说明
使用表达式树构建的查询。从调试监视,查询(返回错误的结果)就像这样
query.Expression:
-----------------
Convert(value(System.Data.Objects.ObjectSet`1[myEFTable]))
.MergeAs(AppendOnly)
.Where(m => ( m.groupId == value(myFilterClass).groupId))
.Where(m => m.status.Contains(value(myFilterClass).statusStr))
.Select(m => new myViewClass()
{
Id = m.id, GroupId = m.groupid, Status = m.status, Name = m.name
})
.OrderBy(o => o.Name).Skip(0).Take(10)
然后我尝试运行类似的查询并返回正确的结果
assume e is ObjectSet<myEFTable> and strGuid is guidA
Guid grId = new Guid(strGuid);
e.AsQueryable()
.Where(m => m.status.Contains("reserved"))
.Where(m => m.groupId == grId)
.Select(m => new myViewClass()
{
Id = m.id, GroupId = m.groupid, Status = m.status, Name = m.name
}).OrderBy(o => o.Name).Skip(0).Take(10);
问题
我完全不知道这个错误..
如果我的EF表格正确并且查询正确,为什么会返回错误的结果?
是因为MergeAs(AppendOnly)
吗?因为唯一不同的是。
如果这是关于唯一键的,我应该如何处理myViewClass
以确保每一行都是唯一的并且不应该合并(如果是这种情况)?
更新2013/08/29
结果不正确,因为我在其中一个查询中有拼写错误。
所以,在改变了很多这里和那里之后,尝试和错误,直到我几乎失去了任何改变,评论,删除的痕迹,突然它的工作.. EUREKA !!什么?
我所做的并不是真的改变了一切,只是做了很多改变,但实际上并没有真正与我开始时有太大不同......所以就是这样!
然后,EUREKA时刻结束,让我追溯到找出真正错误的地方,仅仅因为我不相信奇迹......所以这里是..
这些表实际上与此相似:
PartsGroups
-----------
id name
-----------
1 Nails
-----------
Items
-----------------
id name status
-----------------
2 Table Empty
5 Table Indent
6 Door Empty
3 Sofa Empty
PartsGroupPairs
------------------
id groupId partId
------------------
1 1 4
2 1 7
3 1 8
4 1 15
-------------------
Parts
------------------------
id name itemId status
------------------------
4 XNail 2 Empty
7 SNail 5 Empty
8 UNail 6 Empty
15 ZNail 3 Empty
------------------------
关系就像这样
PartsGroups PartsGroupPairs Parts Items
----------- ------------------ ------------------------ -----------------
id name id groupId partId id name itemId status id name status
----------- ------------------ ------------------------ -----------------
1 Nails 1 1 4 4 XNail 2 Empty 2 Table Empty
1 Nails 2 1 7 7 SNail 5 Empty 5 Table Indent
1 Nails 3 1 8 8 UNail 6 Empty 6 Door Empty
1 Nails 4 1 15 15 ZNail 3 Empty 3 Sofa Empty
----------- ------------------- ------------------------ -----------------
One <---> Many Many <---> One Many <------> One
PartsGroup.pairs is a collection of PartsGroupPairs
PartsGroupPair.group is a PartsGroup
PartsGroupPair.part is a Part
Part.item is an Item
Item.parts is a collection of Parts
因此,当我选择其中name =='Nails'的PartsGroup时,它完美地运行,它返回4行
但是为什么当我选择PartsGroup,其中name =='Nails'和Status =='Empty'时,它会返回3行? (见下文)
PartsGroups PartsGroupPairs Parts Items
----------- ------------------ ------------------------ -----------------
id name id groupId partId id name itemId status id name status
----------- ------------------ ------------------------ -----------------
1 Nails 1 1 4 4 XNail 2 Empty 2 Table Empty
1 Nails 3 1 8 8 UNail 6 Empty 6 Door Empty
1 Nails 4 1 15 15 ZNail 3 Empty 3 Sofa Empty
----------- ------------------- ------------------------ -----------------
这一行没有被选中..
PartsGroups PartsGroupPairs Parts Items
----------- ------------------ ------------------------ -----------------
id name id groupId partId id name itemId status id name status
----------- ------------------ ------------------------ -----------------
1 Nails 2 1 7 7 SNail 5 Empty 5 Table Indent
----------- ------------------- ------------------------ -----------------
我犯的错误是在Where
部分。查询本身在运行时构建,因为我将实体,过滤器,视图和分页模块分开。所以我只是在这里和那里传递IQueryable
。
对于过滤器,每次我过滤,我都会添加另一个。所以在这种情况下,它如下所示:
using(var DB = new databaseContext())
{
ObjectSet<PartsGroupPair> d =
DB.CreateObjectSet<PartsGroupPair>("partsGroupPair");
int searchGroupId = 1; // int instead of guid for example
int searchStatus = "Empty";
// filter by specific PartsGroup
IQueryable<PartsGroupPair> e = d.Where(m => m.group.id == searchGroupId);
// then if I want to filter by the status
e = e.Where(m => m.part.item.status == searchStatus)); // WRONG!!
// I want to filter by part.status, not item.status
// so instead, it should be
e = e.Where(m => m.part.status == searchStatus)); // RIGHT!!
// view
IQueryable<PartsGroupPairView> f =
e.Select(m => new PartsGroupPairView()
{
Id = m.id, GroupId = m.groupid,
Status = m.part.status, Name = m.part.name
// etc..
});
// paging
f = f.OrderBy(o => o.Name).Skip(0).Take(10);
}
错误的过滤使LINQ忽略其他部分,并返回3行而不是4行,因为它只找到一个Item而不是2个部分。
所以在我的情况下,这是一个非常复杂数据的愚蠢错字。
当一切都行不通时,这真的很令人沮丧......