错误的结果可能是因为MergeAs(AppendOnly)LINQ

时间:2013-08-28 12:06:11

标签: linq c#-4.0

注意

这可能是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);

问题

我完全不知道这个错误..

  1. 如果我的EF表格正确并且查询正确,为什么会返回错误的结果?

  2. 是因为MergeAs(AppendOnly)吗?因为唯一不同的是。

  3. 如果这是关于唯一键的,我应该如何处理myViewClass以确保每一行都是唯一的并且不应该合并(如果是这种情况)?

    ----------------------------------------------- ----------------------

  4. 更新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个部分。

    所以在我的情况下,这是一个非常复杂数据的愚蠢错字。

    当一切都行不通时,这真的很令人沮丧......

0 个答案:

没有答案