2008-12-18 46 views
6

我在LINQ查詢上使用OrderBy擴展方法時遇到了一些問題,當它在枚舉類型上運行時。我使用Visual Studio創建了一個常規的DataContext,只需將所有內容拖放到設計器上即可。然後我創建了獨立的實體模型,它們只是POCO的,而且我使用了一個存儲庫模式從我的數據庫中獲取數據並將它們映射到我自己的實體模型中(或者說,我有一個存儲庫模式,可以構建和IQueryable這將做到這一切)。Linq To SQL OrderBy,使用枚舉時發出的問題

一切正常,除非我嘗試在從short/smallint映射到枚舉的屬性上應用OrderBy(在存儲庫之外)。

下面是相關的代碼位:

public class Campaign 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
    .... 
    public CampaignStatus Status { get; set; } 
    ... 
} 
public enum CampaignStatus : short { 
    Active, 
    Inactive, 
    Todo, 
    Hidden 
} 
public class SqlCampaignRepository : ICampaignRepository 
{ 
... 
    public IQueryable<Campaign> Campaigns() 
    { 
     DataContext db = new DataContext(); 
     return from c in db.Campaigns 
       select new Campaign 
        { 
         Id = c.Id, 
         Name = c.Name, 
         ... 
         Status = (CampaignStatus)c.Status, 
         ... 
        }; 
    } 
} 

然後別處

SqlCampaignRepository rep = new SqlCampaignRepository(); 
var query = rep.Campaigns().OrderBy(c => c.Status); 

這觸發了以下異常: System.ArgumentException是由用戶代碼未處理 消息=「參數'值'是錯誤的類型,預期'IQMedia.Models.CampaignType'。實際'System.Int16'。「 源= 「將System.Data.Linq」 堆棧跟蹤: 粘彈性阻尼器System.Data.Linq.SqlClient.SqlOrderExpression.set_Expression(SqlExpression值) 粘彈性阻尼器System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitSelect(一個SQLSelect選擇) VED System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode節點) 粘彈性阻尼器System.Data.Linq.SqlClient.SqlBinder.Visitor.VisitIncludeScope(SqlIncludeScope範圍) ...

(抱歉在那裏丹麥,ved = by/at)。

我已經嘗試了在orderBy表達式中縮短狀態以縮短狀態,但是這並沒有幫助,同樣如果我將它轉換爲實際的枚舉類型也是如此。

任何幫助解決這個問題,非常感謝!

回答

3

您可以通過設計師直接在DataContext中指定類型CampaignStatus嗎?這樣該值會自動映射到enum

1

Campaign class和Campaigns之間有什麼關係?如果Campaigns返回了一組Campaign對象,則請注意您不能正常地映射實體select new

我想知道如果在Select之前執行OrderBy,它會起什麼作用嗎?

最後一招可能是用簡單的TSQL創建一個假的可組合的[Function]。例如,ABS可能就足夠了。即像(上下文):

[Function(Name="ABS", IsComposable=true)] 
    public int Abs(int value) 
    { // to prove not used by our C# code... 
     throw new NotImplementedException(); 
    } 

然後嘗試:

.OrderBy(x => ctx.Abs(x.Status)) 

我沒有測試以上,但可以給它以後去...它適用於一些其他類似的儘管如此。

值得一試...

0

我的DataContext有它自己的命名活動的實體類(生活在一個不同的命名空間,當然)。此外,狀態列在數據庫中保存爲smallint,並且LINQ Entity名稱空間將其類型列爲短(System.Int16)。

如果我在存儲庫中的查詢中應用它,order by的工作 - 這是所有更大的事情的一部分,而整個想法是沒有應用任何類型的存儲庫,過濾或類似的東西,但僅僅將數據庫實體類映射到我自己的類。這個例子顯然有點毫無意義,它幾乎是一個直接的映射,但在某些情況下,我也添加了本地化。

此外我忘了添加 - 異常顯然不會occour,直到我嘗試執行查詢(即 - 調用ToList,或枚舉集合)。

從更大的圖片來看,這個方法被一個服務類所使用,然後這個服務類應該添加過濾,排序和所有這些 - 而且所有這些當然都是爲了分離一些東西,但也允許如果願意,可以輕鬆過渡到不同的數據庫或不同的OR/M。

啊,沒有看到最後一點,直到我回答 - 我還沒有使用函數屬性的任何經驗,但我不會訪問我應該進行排序的類中的datacontext。