2013-08-06 118 views
0

首先爲較差的標題道歉。絕對不知道如何描述這個問題!Linq基於漸進狀態的查詢

我有一個「關係」實體,它定義了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更改時都會創建關係實體。所以對於任何一對用戶來說,都會有很多關係對象。隨着最新的當前。

我試圖查詢任何關係對象,代表特定對用戶在RelationshipState中的減少。

因此,所有用戶的所有RelationshipObjects。該日期比具有更高RelationshipState的日期晚。

我發現很難弄清楚如何在不重複整個關係表的情況下完成此操作。

+0

與實際數據的任何嘗試的某些代碼示例和預期的結果將是非常適合的。 –

回答

1

首先,創建一個查詢以返回列出所有狀態更改的用戶和子組的所有組合。有關更多信息,請參閱Google 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(); 
} 
+0

夢幻般的迴應。不需要ToList。我沒有想過如何移動它自己的團隊。我試圖用子查詢來做到這一點。這是好得多 –

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 

由於看起來效率低下,所以可能值得一試。也許,通過適當的索引和一個好的查詢優化器(以及足夠小的一組數據),它不會那麼糟糕。如果速度慢得難以接受,那麼用光標試用一個存儲過程最有可能是最好的。