0

首先为糟糕的标题道歉。完全不知道如何描述这个问题!

我有一个“关系”实体,它定义了 2 个用户之间的关系。

public class Relationship{
 User User1{get;set;}
 User User2{get;set;}
 DateTime StateChangeDate {get;set;}

 //RelationshipState is an Enum with int values
 State RelationshipState State{get;set;}
}

关系状态示例。

public enum RelationshipState{
 state1 = 1,
 state2 = 2, 
 state3 = 3,
 state4 = 4
}

每次RelationshipState 更改时都会创建一个Relationship 实体。所以对于任何一对用户,都会有很多关系对象。最新的是最新的。

我正在尝试查询代表特定用户对的 RelationshipState 中的 REDUCTION 的任何关系对象。

所以所有用户的所有关系对象。日期比具有更高关系状态的日期晚。

我发现在不遍历整个关系表的情况下很难弄清楚如何做到这一点。

4

2 回答 2

1

首先,创建一个查询以返回所有用户组合和一个列出所有状态更改的子项。更多信息,谷歌 LINQ Group By。

然后使用您的集合,通过查看最后两个状态更改并查看它是否已关闭,过滤掉所有您不想要的。

这是一个示例,在 LinqPad 中作为 C# 程序进行了测试:

public enum RelationshipState {
 state1 = 1,
 state2 = 2, 
 state3 = 3,
 state4 = 4
}
public class User {
   public int id {get;set;}
}
public class Relationship{
 public User User1{get;set;}
 public User User2{get;set;}
 public DateTime StateChangeDate {get;set;}

 //RelationshipState is an Enum with int values
 public RelationshipState State {get;set;}
}

void Main()
{


var rs=new List<Relationship>() {
 new Relationship{ User1=new User{id=1},User2=new User{id=2},StateChangeDate=DateTime.Parse("1/1/2013"),State=RelationshipState.state2},
 new Relationship{ User1=new User{id=1},User2=new User{id=2},StateChangeDate=DateTime.Parse("1/2/2013"),State=RelationshipState.state3},
 new Relationship{ User1=new User{id=1},User2=new User{id=3},StateChangeDate=DateTime.Parse("1/1/2013"),State=RelationshipState.state2},
 new Relationship{ User1=new User{id=1},User2=new User{id=3},StateChangeDate=DateTime.Parse("1/2/2013"),State=RelationshipState.state1},
 new Relationship{ User1=new User{id=2},User2=new User{id=3},StateChangeDate=DateTime.Parse("1/2/3013"),State=RelationshipState.state1}
};

var result=rs.GroupBy(cm=>new {id1=cm.User1.id,id2=cm.User2.id},(key,group)=>new {Key1=key,Group1=group.OrderByDescending(g=>g.StateChangeDate)})
 .Where(r=>r.Group1.Count()>1) // Remove Entries with only 1 status
 //.ToList() // This might be needed for Linq-to-Entities
 .Where(r=>r.Group1.First().State<r.Group1.Skip(1).First().State) // Only keep relationships where the state has gone done
 .Select(r=>r.Group1.First())  //Turn this back into Relationship objects
 ;

// Use this instead if you want to know if state ever had a higher state than it is currently
//  var result=rs.GroupBy(cm=>new {id1=cm.User1.id,id2=cm.User2.id},(key,group)=>new {Key1=key,Group1=group.OrderByDescending(g=>g.StateChangeDate)})
//   .Where(r=>r.Group1.First().State<r.Group1.Max(g=>g.State))
//   .Select(r=>r.Group1.First())
//   ;

result.Dump();
}
于 2013-08-07T06:39:53.437 回答
0

在数据库中创建一个存储过程,它可以使用游标来迭代项目并将它们与它们之前的项目配对(然后过滤到递减状态。)

除此之外,您可以执行内部查询来查找每个项目的先前值:

from item in table
let previous = 
    (from innerItem in table 
    where previous.date < item.Date 
    select innerItem)
    .Max(inner => inner.Date)
where previous.State > item.State
select item

尽管看起来效率低下,但它可能值得一试。也许,有了正确的索引和一个好的查询优化器(和足够小的数据集),它不会那么糟糕。如果速度慢得令人无法接受,那么使用游标尝试存储过程很可能是最好的。

于 2013-08-06T16:09:34.737 回答