AUTHOR: Georgi Georgiev
DATE POSTED: September 19, 2014
public
static
ExpressionBuilder Instance
{
get
if
(instance ==
null
)
lock
(syncRoot)
instance =
new
ExpressionBuilder();
}
return
instance;
bool
Optimize<T>(IQueryable<T> collection)
(
this
.optimizationCache.Contains(
typeof
(T)))
false
;
.optimizationCache.Add(
(T));
collection.ToList();
true
Public
Shared
ReadOnly
Property
Instance()
As
ExpressionBuilder
Get
If
instance
Is
Nothing
Then
SyncLock
syncRoot
New
ExpressionBuilder()
End
Return
Function
Optimize(Of T)(collection
IQueryable(Of T))
Boolean
Me
GetType
(T))
False
collection.ToList()
True
Expression<Func<T, TResult>> BuildMethodCallExpression<T, TResult>(
string
parameter,
property, Type ownerType,
methodName,
int
parametersCount)
var param = Expression.Parameter(
var constant = Expression.Constant(parameter);
var prop = Expression.Property(param, property);
var method = ownerType.GetMethods().First(x => x.Name == methodName && x.GetParameters().Length == parametersCount);
var body = Expression.Call(prop, method, constant);
Expression.Lambda<Func<T, TResult>>(body, param);
Expression<Func<T,
>> BuildContainsExpression<T>(
property,
filter)
var dataItemsExp =
.BuildMethodCallExpression<T,
>(filter, property,
(String),
"Contains"
, 1);
dataItemsExp;
>> BuildSelectExpression<T>(
property)
var expression = Expression.Lambda<Func<T,
>>(prop, param);
expression;
>> BuildStartsWithExpression<T>(
var lambda =
"StartsWith"
var newBody = Expression.And(lambda.Body,
Expression.NotEqual(Expression.Property(lambda.Parameters.First(), property), Expression.Constant(filter)));
var newExpression = Expression.Lambda<Func<T,
>>(newBody, lambda.Parameters);
newExpression;
BuildMethodCallExpression(Of T, TResult)(parameter
String
, [property]
, ownerType
Type, methodName
, parametersCount
Integer
Expression(Of Func(Of T, TResult))
Dim
param = Expression.Parameter(
constant = Expression.Constant(parameter)
prop = Expression.[
](param, [property])
method = ownerType.GetMethods().First(
(x) x.Name = methodName
AndAlso
x.GetParameters().Length = parametersCount)
body = Expression.[
Call
](prop, method, constant)
Expression.Lambda(Of Func(Of T, TResult))(body, param)
BuildContainsExpression(Of T)([property]
, filter
Expression(Of Func(Of T,
))
dataItemsExp =
.BuildMethodCallExpression(Of T,
)(filter, [property],
([
]),
, 1)
dataItemsExp
BuildSelectExpression(Of T)([property]
expression__1 = Expression.Lambda(Of Func(Of T,
))(prop, param)
expression__1
BuildStartsWithExpression(Of T)([property]
lambda =
newBody = Expression.[
And
](lambda.Body, Expression.NotEqual(Expression.[
](lambda.Parameters.First(), [property]), Expression.Constant(filter)))
newExpression = Expression.Lambda(Of Func(Of T,
))(newBody, lambda.Parameters)
newExpression
class
ServerAutoCompleteAppendHelper<T> : AutoCompleteAppendHelper
IQueryable<T> Data {
private
set
; }
ServerAutoCompleteAppendHelper(RadDropDownListElement owner, IEnumerable<T> data)
:
base
(owner)
.Data = data.AsQueryable();
ExpressionBuilder.Instance.Optimize(
.Data);
override
void
AutoComplete(KeyPressEventArgs e)
findString =
.CreateFindString(e);
var whereExp = ExpressionBuilder.Instance.BuildStartsWithExpression<T>(
.Owner.AutoCompleteValueMember, findString);
var selectExp = ExpressionBuilder.Instance.BuildSelectExpression<T>(
.Owner.AutoCompleteValueMember);
result =
.Data.Where(whereExp).Select(selectExp).OrderBy(x => x.Length).FirstOrDefault();
(result !=
Owner.EditableElementText = result;
Owner.SelectionStart = findString.Length;
Owner.SelectionLength = Owner.EditableElementText.Length;
e.Handled =
CreateFindString(KeyPressEventArgs e)
""
(Owner.SelectionLength == 0)
findString = Owner.EditableElementText + e.KeyChar;
else
findString = Owner.EditableElementText.Substring(0, Owner.SelectionStart) + e.KeyChar;
findString;
Class
ServerAutoCompleteAppendHelper(Of T)
Inherits
AutoCompleteAppendHelper
Data()
IQueryable(Of T)
m_Data
Private
Set
m_Data = Value
Sub
(owner
RadDropDownListElement, data
IEnumerable(Of T))
MyBase
.
.Data = data.AsQueryable()
.Data)
Overrides
AutoComplete(e
KeyPressEventArgs)
findString
=
.CreateFindString(e)
whereExp = ExpressionBuilder.Instance.BuildStartsWithExpression(Of T)(
.Owner.AutoCompleteValueMember, findString)
selectExp = ExpressionBuilder.Instance.BuildSelectExpression(Of T)(
.Owner.AutoCompleteValueMember)
result
.Data.Where(whereExp).[
Select
](selectExp).OrderBy(
(x) x.Length).FirstOrDefault()
result IsNot
Owner.EditableElementText = result
Owner.SelectionStart = findString.Length
Owner.SelectionLength = Owner.EditableElementText.Length
CreateFindString(e
Owner.SelectionLength = 0
findString = Owner.EditableElementText + e.KeyChar
Else
findString = Owner.EditableElementText.Substring(0, Owner.SelectionStart) + e.KeyChar
ServerAutoCompleteSuggestHelper<T> : AutoCompleteSuggestHelper
MaxItems {
ServerAutoCompleteSuggestHelper(RadDropDownListElement owner, IEnumerable<T> data,
maxItems = 1000)
.MaxItems = maxItems;
ApplyFilterToDropDown(
.DropDownList.BeginUpdate();
.DropDownList.ListElement.Items.Clear();
var dataItemsExp = ExpressionBuilder.Instance.BuildContainsExpression<T>(
.Owner.AutoCompleteValueMember, filter);
var dataItemsQuery =
.Data.Where(dataItemsExp).Take(
.MaxItems);
var dataItems = dataItemsQuery.ToList();
var displayItemsQuery = dataItemsQuery.Select(selectExp);
var displayItems = displayItemsQuery.ToList();
for
i = 0; i < dataItems.Count; i++)
var dataItem = dataItems[i];
var displayMember = displayItems[i];
.DropDownList.ListElement.Items.Add(
RadListDataItem(displayMember, dataItem));
.DropDownList.EndUpdate();
.Owner.SelectionLength =
.Owner.Text.Length;
ServerAutoCompleteSuggestHelper(Of T)
AutoCompleteSuggestHelper
MaxItems()
m_MaxItems
m_MaxItems = Value
IEnumerable(Of T),
Optional
maxItems
= 1000)
.MaxItems = maxItems
ApplyFilterToDropDown(filter
.DropDownList.BeginUpdate()
.DropDownList.ListElement.Items.Clear()
dataItemsExp = ExpressionBuilder.Instance.BuildContainsExpression(Of T)(
.Owner.AutoCompleteValueMember, filter)
dataItemsQuery =
.MaxItems)
dataItems = dataItemsQuery.ToList()
displayItemsQuery = dataItemsQuery.[
](selectExp)
displayItems = displayItemsQuery.ToList()
For
i
= 0
To
dataItems.Count - 1
dataItem = dataItems(i)
displayMember = displayItems(i)
RadListDataItem(displayMember, dataItem))
Next
.DropDownList.EndUpdate()
.Owner.Text.Length
RadDropDownList list =
RadDropDownList
Parent =
,
Dock = DockStyle.Top
};
LargeDataEntities dbContext =
LargeDataEntities();
list.AutoCompleteValueMember =
"Name"
list.DropDownListElement.AutoCompleteSuggest =
ServerAutoCompleteSuggestHelper<Datum>(list.DropDownListElement, dbContext.Data);
list.DropDownListElement.AutoCompleteAppend =
ServerAutoCompleteAppendHelper<Datum>(list.DropDownListElement, dbContext.Data);
list
RadDropDownList()
With
{ _
.Parent =
, _
.Dock = DockStyle.Top _
dbContext
LargeDataEntities()
list.DropDownListElement.AutoCompleteValueMember =
ServerAutoCompleteSuggestHelper(Of Datum)(list.DropDownListElement, dbContext.Data)
ServerAutoCompleteAppendHelper(Of Datum)(list.DropDownListElement, dbContext.Data)
Resources Buy Try