2011-10-13 60 views
0

我們正在使用實體框架(MySQL連接器)並在我們的Web應用程序上創建中央搜索工具。Linq to Entities複雜的動態搜索

This link幾乎正是我所需要的,除了他使用預定義的實體和屬性。在我們的搜索場景中,我們將擁有動態數量的搜索字詞和字段(即:用戶選擇搜索姓氏,價值和城市,或提供商和顧問)。

是否有可能通過LINQ實現這種功能,以便我們可以利用延遲加載機制?如果可能,我真的很想避免生成SQL字符串。我看着Dynamic LINQ with Expression Trees,但不能得到這個工作(或this)。

+0

你可以提供更多信息,你的輸入是如何更動態的,然後從第一個鏈接輸入數據。也許你嘗試過一個簡單的例子,希望你想實現。 – esskar

回答

0

我知道你表示你想避免生成SQL字符串,但這通常是最簡單的方法。 (比自定義表達式樹更容易)。如果你在EF中這樣做,我建議你查看Entity Sql,它對你的概念模型起作用,但允許比LINQ更加動態的查詢選項。 LINQ非常適合編譯時間查詢而不是運行時查詢。您可以在http://msdn.microsoft.com/en-us/library/bb387145.aspx上閱讀實體SQL。

+0

建議回到SQL,因爲它很容易,根本不是一個好的選擇。 – esskar

+0

我不推薦回到SQL,我建議轉到實體SQL。 –

0

從上週開始,我們遇到了類似的問題,這裏有一個想法。以爲我與你分享。

interface IPerson 
{    
    DateTime BirthDay { get; set; } 

    string City { get; set; }    

    string FirstName { get; set; } 

    string LastName { get; set; } 
} 

interface IFilter { } 

interface IPersonFilter : IFilter { } 

class PersonFilter : IPersonFilter 
{    
    public DateTime? BirthDay { get; set; } 

    public string City { get; set; } 

    public string FirstName { get; set; } 

    public string LastName { get; set; }    
} 

static IQueryable<TSource> ApplyFilter<TSource, TFilter>(IQueryable<TSource> source, TFilter filter) where TFilter : IFilter 
{ 
    const BindingFlags bindingFlags = BindingFlags.Public|BindingFlags.Instance|BindingFlags.GetProperty; 

    var retval = source; 
    foreach (var filterProperty in filter.GetType().GetProperties(bindingFlags)) 
    { 
     var elementParameter = Expression.Parameter(source.ElementType, "type"); 
     var elementProperty = Expression.Property(elementParameter, filterProperty.Name); 

     var value = filterProperty.GetGetMethod().Invoke(filter, null); 
     if (value != null) 
     { 
      var constantValue = Expression.Constant(value, elementProperty.Type); 
      var expression = Expression.Equal(elementProperty, constantValue); 
      retval = retval.Where(Expression.Lambda<Func<TSource, bool>>(expression, elementParameter)); 
     } 
    } 

    return retval; 
} 

這樣的想法是,你有一個過濾器,過濾器的屬性的名稱相匹配要運行對過濾器的對象的屬性名稱。如果該屬性的值不爲空,我爲它建立一個表達式。爲了簡單起見,我僅構建Expression.Equal表達式,但我正在考慮對其進行擴展。