2013-01-10 37 views
0

我想讓這個工作幾個小時。我嘗試過這些例子並閱讀文檔,但我無法弄清楚。查詢不同的值

我想用名稱字段從數據庫查詢不同的值。 我認爲這應該工作,但事實並非如此。鮮明的方法,沒有找到

[HttpGet] 
    public IQueryable<MvlOP> MvlOpsPerson(long mvlId) 
    { 
     System.Data.Entity.Infrastructure.DbQuery<MvlOP> query = ContextProvider.Context.MvlOps; 

     query = query.Include("StatusOP"); 
     return query.Where(op => op.MvlId == mvlId).Distinct(new PropertyComparer<MvlOP>("Id_P")); 
    } 

我得到以下錯誤:

ExceptionMessage=LINQ to Entities does not recognize the method 'System.Linq.IQueryable`1[MAHN.Model.MvlOP] Distinct[MvlOP](System.Linq.IQueryable`1[MAHN.Model.MvlOP], System.Collections.Generic.IEqualityComparer`1[MAHN.Model.MvlOP])' method, and this method cannot be translated into a store expression. 

ExceptionType = System.NotSupportedException

因此,這是錯誤的。據我瞭解,微風不提供查詢不同的價值觀。查詢全部和篩選不是一個選項。任何幫助如何做到這一點大加讚賞。

回答

0

我認爲問題是實體框架(EF)不能使用您的PropertyComparer。 EF僅支持Distinct而沒有比較器。

1

我張貼這個,讓有人可能需要它可以使用它。也許這可以通過某種方式得到改善。 (受Breeze DocCode啓發(感謝Northwind控制器中的部分類Api方法:))

查詢不同的值可以這樣完成: 爲了能夠使用Distinct(IEqualityComparer)方法,查詢必須是在內存中作爲IEnumerable。 EqualityComparer不能被翻譯成SQL語句。 因此where子句適用,然後結果記錄被比較器過濾。

return query.AsQueryable():爲了能夠使用skip/take和inlineCount,查詢必須是IQueryable<T>。因此,方法AsQueryable()

//The API Method ---------- 
[HttpGet] 
    public IQueryable<MvlOPPersonPartial> MvlOpsPerson(long mvlId) 
    { 
     var query = (from op in ContextProvider.Context.MvlOps 
         where op.MvlId == mvlId 
         select new MvlOPPersonPartial() 
          { 
           MvlId = op.MvlId, 
           Kundenname = op.Kundenname, 
           Kundennummer = op.Kundennummer, 
           Id_P = op.Id_P 
          }) 
          .AsEnumerable() 
          .Distinct(new PropertyComparer<MvlOPPersonPartial>("Id_P")); 
     return query.AsQueryable(); 
    } 

public class MvlOp 
{ 
... 
    public string Kostenstelle { get; set; } 
    public string Betreuer_Id { get; set; } 
    public decimal? Id_P { get; set; } 
    public string Kundenname { get; set; } 
    public string Kundennummer { get; set; } 
    public string Person_Typ1 { get; set; } 
... 
} 


//The partial class needed for distinct values ------------ 
//MvlOP cannot be constructed in an LINQ to Entities query 
public class MvlOPPersonPartial 
{ 
    public long MvlId { get; set; } 
    public string Kundenname { get; set; } 
    public string Kundennummer { get; set; } 
    public decimal? Id_P { get; set; } 
} 


//A generic comparer --------------- 
public class PropertyComparer<T> : IEqualityComparer<T> 
{ 
    private PropertyInfo _PropertyInfo; 

    /// <summary> 
    /// Creates a new instance of PropertyComparer. 
    /// </summary> 
    /// <param name="propertyName">The name of the property on type T 
    /// to perform the comparison on.</param> 
    public PropertyComparer(string propertyName) 
    { 
     //store a reference to the property info object for use during the comparison 
     _PropertyInfo = typeof(T).GetProperty(propertyName, 
    BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.Public); 
     if (_PropertyInfo == null) 
     { 
      throw new ArgumentException(string.Format("{0} is not a property of type {1}.", propertyName, typeof(T))); 
     } 
    } 

    #region IEqualityComparer<T> Members 

    public bool Equals(T x, T y) 
    { 
     //get the current value of the comparison property of x and of y 
     object xValue = _PropertyInfo.GetValue(x, null); 
     object yValue = _PropertyInfo.GetValue(y, null); 

     //if the xValue is null then we consider them equal if and only if yValue is null 
     if (xValue == null) 
      return yValue == null; 

     //use the default comparer for whatever type the comparison property is. 
     return xValue.Equals(yValue); 
    } 

    public int GetHashCode(T obj) 
    { 
     //get the value of the comparison property out of obj 
     object propertyValue = _PropertyInfo.GetValue(obj, null); 

     if (propertyValue == null) 
      return 0; 

     else 
      return propertyValue.GetHashCode(); 
    } 

    #endregion 
} 
+0

這是Sascha的作品。讓我們提醒讀者,「AsEnumerable()」之後的所有內容都發生在服務器內存中。您應該知道,該點處的數據集將被檢索到服務器,並且該數據集的後續處理(包括來自客戶端的DISTINCT和任何其他過濾條件)將在服務器上進行,而不是在數據層上進行。沒關係......除非數據集可能在數百萬之內。 – Ward

+0

如果有人想出一個想讓數據庫這樣做的想法,我會很樂意將我的解決方案換掉。到目前爲止,我沒有找到。 –