You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
@@ -0,0 +1,40 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System.Web.Query.Dynamic;
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using System.Security.Permissions;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
[
|
||||
PersistChildren(false),
|
||||
ParseChildren(true, "Parameters")
|
||||
]
|
||||
public class CustomExpression : ParameterDataSourceExpression {
|
||||
private EventHandler<CustomExpressionEventArgs> _querying;
|
||||
|
||||
public event EventHandler<CustomExpressionEventArgs> Querying {
|
||||
add {
|
||||
_querying += value;
|
||||
}
|
||||
remove {
|
||||
_querying -= value;
|
||||
}
|
||||
}
|
||||
|
||||
public override IQueryable GetQueryable(IQueryable source) {
|
||||
CustomExpressionEventArgs e = new CustomExpressionEventArgs(source, GetValues());
|
||||
OnQuerying(e);
|
||||
return e.Query;
|
||||
}
|
||||
|
||||
private void OnQuerying(CustomExpressionEventArgs e) {
|
||||
if (_querying != null) {
|
||||
_querying(this, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Permissions;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class CustomExpressionEventArgs : EventArgs {
|
||||
public IQueryable Query { get; set; }
|
||||
public IDictionary<string, object> Values { get; private set; }
|
||||
|
||||
public CustomExpressionEventArgs(IQueryable source, IDictionary<string, object> values) {
|
||||
Query = source;
|
||||
Values = values;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
|
||||
public abstract class DataSourceExpression : IStateManager {
|
||||
private bool _tracking;
|
||||
private StateBag _viewState;
|
||||
|
||||
protected HttpContext Context {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
protected Control Owner {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public IQueryableDataSource DataSource {
|
||||
get;
|
||||
// Internal set for unit testing
|
||||
internal set;
|
||||
}
|
||||
|
||||
|
||||
protected bool IsTrackingViewState {
|
||||
get {
|
||||
return _tracking;
|
||||
}
|
||||
}
|
||||
|
||||
[
|
||||
Browsable(false),
|
||||
DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
|
||||
]
|
||||
protected StateBag ViewState {
|
||||
get {
|
||||
if (_viewState == null) {
|
||||
_viewState = new StateBag();
|
||||
if (_tracking)
|
||||
((IStateManager)_viewState).TrackViewState();
|
||||
}
|
||||
return _viewState;
|
||||
}
|
||||
}
|
||||
|
||||
protected DataSourceExpression() {
|
||||
}
|
||||
|
||||
// internal for unit testing
|
||||
internal DataSourceExpression(Control owner) {
|
||||
Owner = owner;
|
||||
}
|
||||
|
||||
public void SetDirty() {
|
||||
ViewState.SetDirty(true);
|
||||
}
|
||||
|
||||
protected virtual void LoadViewState(object savedState) {
|
||||
if (savedState != null) {
|
||||
((IStateManager)ViewState).LoadViewState(savedState);
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual object SaveViewState() {
|
||||
return (_viewState != null) ? ((IStateManager)_viewState).SaveViewState() : null;
|
||||
}
|
||||
|
||||
protected virtual void TrackViewState() {
|
||||
_tracking = true;
|
||||
|
||||
if (_viewState != null) {
|
||||
((IStateManager)_viewState).TrackViewState();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract IQueryable GetQueryable(IQueryable source);
|
||||
|
||||
public virtual void SetContext(Control owner, HttpContext context, IQueryableDataSource dataSource) {
|
||||
if (owner == null) {
|
||||
throw new ArgumentNullException("owner");
|
||||
}
|
||||
|
||||
if (context == null) {
|
||||
throw new ArgumentNullException("context");
|
||||
}
|
||||
|
||||
if (dataSource == null) {
|
||||
throw new ArgumentNullException("dataSource");
|
||||
}
|
||||
|
||||
Owner = owner;
|
||||
Context = context;
|
||||
DataSource = dataSource;
|
||||
}
|
||||
|
||||
#region IStateManager Members
|
||||
|
||||
bool IStateManager.IsTrackingViewState {
|
||||
get {
|
||||
return IsTrackingViewState;
|
||||
}
|
||||
}
|
||||
|
||||
void IStateManager.LoadViewState(object state) {
|
||||
LoadViewState(state);
|
||||
}
|
||||
|
||||
object IStateManager.SaveViewState() {
|
||||
return SaveViewState();
|
||||
}
|
||||
|
||||
void IStateManager.TrackViewState() {
|
||||
TrackViewState();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System.Collections;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
|
||||
public class DataSourceExpressionCollection : StateManagedCollection {
|
||||
private IQueryableDataSource _dataSource;
|
||||
|
||||
private static readonly Type[] knownTypes = new Type[] {
|
||||
typeof(SearchExpression),
|
||||
typeof(MethodExpression),
|
||||
typeof(OrderByExpression),
|
||||
typeof(RangeExpression),
|
||||
typeof(PropertyExpression),
|
||||
typeof(CustomExpression),
|
||||
};
|
||||
|
||||
public HttpContext Context {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public Control Owner {
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public DataSourceExpression this[int index] {
|
||||
get {
|
||||
return (DataSourceExpression)((IList)this)[index];
|
||||
}
|
||||
set {
|
||||
((IList)this)[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Allows for nested expression blocks to be initilaized after the fact
|
||||
internal void SetContext(Control owner, HttpContext context, IQueryableDataSource dataSource) {
|
||||
Owner = owner;
|
||||
Context = context;
|
||||
_dataSource = dataSource;
|
||||
|
||||
foreach (DataSourceExpression expression in this) {
|
||||
expression.SetContext(owner, context, _dataSource);
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(DataSourceExpression expression) {
|
||||
((IList)this).Add(expression);
|
||||
}
|
||||
|
||||
protected override object CreateKnownType(int index) {
|
||||
switch (index) {
|
||||
case 0:
|
||||
return new SearchExpression();
|
||||
case 1:
|
||||
return new MethodExpression();
|
||||
case 2:
|
||||
return new OrderByExpression();
|
||||
case 3:
|
||||
return new RangeExpression();
|
||||
case 4:
|
||||
return new PropertyExpression();
|
||||
case 5:
|
||||
return new CustomExpression();
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyTo(DataSourceExpression[] expressionArray, int index) {
|
||||
base.CopyTo(expressionArray, index);
|
||||
}
|
||||
|
||||
public void Contains(DataSourceExpression expression) {
|
||||
((IList)this).Contains(expression);
|
||||
}
|
||||
|
||||
protected override Type[] GetKnownTypes() {
|
||||
return knownTypes;
|
||||
}
|
||||
|
||||
public int IndexOf(DataSourceExpression expression) {
|
||||
return ((IList)this).IndexOf(expression);
|
||||
}
|
||||
|
||||
public void Insert(int index, DataSourceExpression expression) {
|
||||
((IList)this).Insert(index, expression);
|
||||
}
|
||||
|
||||
public void Remove(DataSourceExpression expression) {
|
||||
((IList)this).Remove(expression);
|
||||
}
|
||||
|
||||
public void RemoveAt(int index) {
|
||||
((IList)this).RemoveAt(index);
|
||||
}
|
||||
|
||||
protected override void SetDirtyObject(object o) {
|
||||
((DataSourceExpression)o).SetDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
internal static class ExpressionHelper {
|
||||
public static Expression GetValue(Expression exp) {
|
||||
Type realType = GetUnderlyingType(exp.Type);
|
||||
if (realType == exp.Type) {
|
||||
return exp;
|
||||
}
|
||||
return Expression.Convert(exp, realType);
|
||||
}
|
||||
|
||||
public static Type GetUnderlyingType(Type type) {
|
||||
// Get the type from Nullable types
|
||||
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) {
|
||||
return type.GetGenericArguments()[0];
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public static object BuildObjectValue(object value, Type type) {
|
||||
return System.Web.UI.WebControls.DataSourceHelper.BuildObjectValue(value, type, String.Empty);
|
||||
}
|
||||
|
||||
public static Expression CreatePropertyExpression(Expression parameterExpression, string propertyName) {
|
||||
if (parameterExpression == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(propertyName)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Expression propExpression = null;
|
||||
string[] props = propertyName.Split('.');
|
||||
foreach (var p in props) {
|
||||
if (propExpression == null) {
|
||||
propExpression = Expression.PropertyOrField(parameterExpression, p);
|
||||
}
|
||||
else {
|
||||
propExpression = Expression.PropertyOrField(propExpression, p);
|
||||
}
|
||||
}
|
||||
return propExpression;
|
||||
}
|
||||
|
||||
|
||||
public static IQueryable Where(this IQueryable source, LambdaExpression lambda) {
|
||||
return Call(source, "Where", lambda, source.ElementType);
|
||||
}
|
||||
|
||||
public static IQueryable Call(this IQueryable source, string queryMethod, Type[] genericArgs, params Expression[] arguments) {
|
||||
if (source == null) {
|
||||
throw new ArgumentNullException("source");
|
||||
}
|
||||
return source.Provider.CreateQuery(
|
||||
Expression.Call(
|
||||
typeof(Queryable), queryMethod,
|
||||
genericArgs,
|
||||
arguments));
|
||||
}
|
||||
|
||||
public static IQueryable Call(this IQueryable source, string queryableMethod, LambdaExpression lambda, params Type[] genericArgs) {
|
||||
if (source == null) {
|
||||
throw new ArgumentNullException("source");
|
||||
}
|
||||
return source.Provider.CreateQuery(
|
||||
Expression.Call(
|
||||
typeof(Queryable), queryableMethod,
|
||||
genericArgs,
|
||||
source.Expression, Expression.Quote(lambda)));
|
||||
}
|
||||
|
||||
public static Expression Or(IEnumerable<Expression> expressions) {
|
||||
Expression orExpression = null;
|
||||
foreach (Expression e in expressions) {
|
||||
if (e == null) {
|
||||
continue;
|
||||
}
|
||||
if (orExpression == null) {
|
||||
orExpression = e;
|
||||
}
|
||||
else {
|
||||
orExpression = Expression.OrElse(orExpression, e);
|
||||
}
|
||||
}
|
||||
return orExpression;
|
||||
}
|
||||
|
||||
public static Expression And(IEnumerable<Expression> expressions) {
|
||||
Expression andExpression = null;
|
||||
foreach (Expression e in expressions) {
|
||||
if (e == null) {
|
||||
continue;
|
||||
}
|
||||
if (andExpression == null) {
|
||||
andExpression = e;
|
||||
}
|
||||
else {
|
||||
andExpression = Expression.AndAlso(andExpression, e);
|
||||
}
|
||||
}
|
||||
return andExpression;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Web.Compilation;
|
||||
using System.Web.DynamicData;
|
||||
using System.Web.Resources;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
public class MethodExpression : ParameterDataSourceExpression {
|
||||
private static readonly BindingFlags MethodFlags = BindingFlags.Static | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy;
|
||||
|
||||
// We'll populate a list of ways to get the type
|
||||
private Func<Type>[] typeGetters;
|
||||
|
||||
public string TypeName {
|
||||
get {
|
||||
return (string)ViewState["TypeName"] ?? String.Empty;
|
||||
}
|
||||
set {
|
||||
ViewState["TypeName"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string MethodName {
|
||||
get {
|
||||
return (string)ViewState["MethodName"] ?? String.Empty;
|
||||
}
|
||||
set {
|
||||
ViewState["MethodName"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IgnoreIfNotFound {
|
||||
get {
|
||||
object o = ViewState["IgnoreIfNotFound"];
|
||||
return o != null ? (bool)o : false;
|
||||
}
|
||||
set {
|
||||
ViewState["IgnoreIfNotFound"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public MethodExpression() {
|
||||
// 1. If a TypeName is specified find the method on that type.
|
||||
// 2. Otherwise, if the DataSource is an IDynamicDataSource, then use context type and search for the method.
|
||||
// 3. Otherwise look for the method on the current TemplateControl (Page/UserControl) etc.
|
||||
typeGetters = new Func<Type>[] {
|
||||
() => GetType(TypeName),
|
||||
() => GetType(DataSource),
|
||||
() => (Owner != null && Owner.TemplateControl != null) ? Owner.TemplateControl.GetType() : null
|
||||
};
|
||||
}
|
||||
|
||||
private static Type GetType(string typeName) {
|
||||
if (!String.IsNullOrEmpty(typeName)) {
|
||||
return BuildManager.GetType(typeName, false /* throwOnError */, true /* ignoreCase */);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Type GetType(IQueryableDataSource dataSource) {
|
||||
IDynamicDataSource dynamicDataSource = dataSource as IDynamicDataSource;
|
||||
if (dynamicDataSource != null) {
|
||||
return dynamicDataSource.ContextType;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal MethodInfo ResolveMethod() {
|
||||
if (String.IsNullOrEmpty(MethodName)) {
|
||||
throw new InvalidOperationException(AtlasWeb.MethodExpression_MethodNameMustBeSpecified);
|
||||
}
|
||||
|
||||
MethodInfo methodInfo = null;
|
||||
// We allow the format string {0} in the method name
|
||||
IDynamicDataSource dataSource = DataSource as IDynamicDataSource;
|
||||
if (dataSource != null) {
|
||||
MethodName = String.Format(CultureInfo.CurrentCulture, MethodName, dataSource.EntitySetName);
|
||||
}
|
||||
else if (MethodName.Contains("{0}")) {
|
||||
// If method has a format string but no IDynamicDataSource then throw an exception
|
||||
throw new InvalidOperationException(AtlasWeb.MethodExpression_DataSourceMustBeIDynamicDataSource);
|
||||
}
|
||||
|
||||
foreach (Func<Type> typeGetter in typeGetters) {
|
||||
Type type = typeGetter();
|
||||
// If the type is null continue to next fall back function
|
||||
if (type == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
methodInfo = type.GetMethod(MethodName, MethodFlags);
|
||||
if (methodInfo != null) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return methodInfo;
|
||||
}
|
||||
|
||||
public override IQueryable GetQueryable(IQueryable source) {
|
||||
if (source == null) {
|
||||
throw new ArgumentNullException("source");
|
||||
}
|
||||
|
||||
MethodInfo method = ResolveMethod();
|
||||
|
||||
// Get the parameter values
|
||||
IDictionary<string, object> parameterValues = GetValues();
|
||||
|
||||
if (method == null) {
|
||||
if (IgnoreIfNotFound) {
|
||||
// Unchange the IQueryable if the user set IgnoreIfNotFound
|
||||
return source;
|
||||
}
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture,
|
||||
AtlasWeb.MethodExpression_MethodNotFound, MethodName));
|
||||
}
|
||||
|
||||
if(!method.IsStatic) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
|
||||
AtlasWeb.MethodExpression_MethodMustBeStatic, MethodName));
|
||||
}
|
||||
|
||||
ParameterInfo[] parameterArray = method.GetParameters();
|
||||
if (parameterArray.Length == 0 || !parameterArray[0].ParameterType.IsAssignableFrom(source.GetType())) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.MethodExpression_FirstParamterMustBeCorrectType,
|
||||
MethodName, source.GetType()));
|
||||
}
|
||||
|
||||
object[] arguments = new object[parameterArray.Length];
|
||||
// First argument is the IQueryable
|
||||
arguments[0] = source;
|
||||
for (int i = 1; i < parameterArray.Length; ++i) {
|
||||
ParameterInfo param = parameterArray[i];
|
||||
object value;
|
||||
if (!parameterValues.TryGetValue(param.Name, out value)) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
|
||||
AtlasWeb.MethodExpression_ParameterNotFound, MethodName, param.Name));
|
||||
}
|
||||
|
||||
arguments[i] = DataSourceHelper.BuildObjectValue(value, param.ParameterType, param.Name);
|
||||
}
|
||||
|
||||
object result = method.Invoke(null, arguments);
|
||||
|
||||
// Require the return type be the same as the parameter type
|
||||
if (result != null) {
|
||||
IQueryable queryable = result as IQueryable;
|
||||
// Check if the user did a projection (changed the T in IQuerable<T>)
|
||||
if (queryable == null || !queryable.ElementType.IsAssignableFrom(source.ElementType)) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, AtlasWeb.MethodExpression_ChangingTheReturnTypeIsNotAllowed,
|
||||
source.ElementType.FullName));
|
||||
}
|
||||
}
|
||||
|
||||
return (IQueryable)result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using System.Web.Compilation;
|
||||
using System.Web.Resources;
|
||||
using System;
|
||||
using System.Web.UI;
|
||||
|
||||
public class OfTypeExpression : DataSourceExpression {
|
||||
private MethodInfo _ofTypeMethod;
|
||||
private string _typeName;
|
||||
|
||||
private MethodInfo OfTypeMethod {
|
||||
get {
|
||||
if (_ofTypeMethod == null) {
|
||||
var type = GetType(TypeName);
|
||||
|
||||
_ofTypeMethod = GetOfTypeMethod(type);
|
||||
}
|
||||
return _ofTypeMethod;
|
||||
}
|
||||
}
|
||||
|
||||
[DefaultValue("")]
|
||||
public string TypeName {
|
||||
get {
|
||||
return _typeName ?? String.Empty;
|
||||
}
|
||||
set {
|
||||
if (TypeName != value) {
|
||||
_typeName = value;
|
||||
_ofTypeMethod = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public OfTypeExpression() {
|
||||
}
|
||||
|
||||
public OfTypeExpression(Type type) {
|
||||
if (type == null) {
|
||||
throw new ArgumentNullException("type");
|
||||
}
|
||||
TypeName = type.AssemblyQualifiedName;
|
||||
_ofTypeMethod = GetOfTypeMethod(type);
|
||||
}
|
||||
|
||||
// internal for unit testing
|
||||
internal OfTypeExpression(Control owner)
|
||||
: base(owner) {
|
||||
}
|
||||
|
||||
private Type GetType(string typeName) {
|
||||
if (String.IsNullOrEmpty(typeName)) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
|
||||
AtlasWeb.OfTypeExpression_TypeNameNotSpecified,
|
||||
Owner.ID));
|
||||
}
|
||||
try {
|
||||
return BuildManager.GetType(typeName, true /* throwOnError */, true /* ignoreCase */);
|
||||
} catch (Exception e) {
|
||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture,
|
||||
AtlasWeb.OfTypeExpression_CannotFindType,
|
||||
typeName,
|
||||
Owner.ID), e);
|
||||
}
|
||||
}
|
||||
|
||||
private static MethodInfo GetOfTypeMethod(Type type) {
|
||||
Debug.Assert(type != null);
|
||||
return typeof(Queryable).GetMethod("OfType").MakeGenericMethod(new Type[] { type });
|
||||
}
|
||||
|
||||
public override IQueryable GetQueryable(IQueryable query) {
|
||||
return query.Provider.CreateQuery(Expression.Call(null, OfTypeMethod, query.Expression));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Web.Resources;
|
||||
using System.Web.UI;
|
||||
|
||||
[
|
||||
PersistChildren(false),
|
||||
ParseChildren(true, "ThenByExpressions")
|
||||
]
|
||||
public class OrderByExpression : DataSourceExpression {
|
||||
private const string OrderByMethod = "OrderBy";
|
||||
private const string ThenByMethod = "ThenBy";
|
||||
private const string OrderDescendingByMethod = "OrderByDescending";
|
||||
private const string ThenDescendingByMethod = "ThenByDescending";
|
||||
|
||||
private Collection<ThenBy> _thenByExpressions;
|
||||
|
||||
public string DataField {
|
||||
get {
|
||||
return (string)ViewState["DataField"] ?? String.Empty;
|
||||
}
|
||||
set {
|
||||
ViewState["DataField"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public SortDirection Direction {
|
||||
get {
|
||||
object o = ViewState["Direction"];
|
||||
return o != null ? (SortDirection)o : SortDirection.Ascending;
|
||||
}
|
||||
set {
|
||||
ViewState["Direction"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
|
||||
public Collection<ThenBy> ThenByExpressions {
|
||||
get {
|
||||
if (_thenByExpressions == null) {
|
||||
//
|
||||
_thenByExpressions = new Collection<ThenBy>();
|
||||
}
|
||||
return _thenByExpressions;
|
||||
}
|
||||
}
|
||||
|
||||
public override IQueryable GetQueryable(IQueryable source) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(DataField)) {
|
||||
throw new InvalidOperationException(AtlasWeb.Expressions_DataFieldRequired);
|
||||
}
|
||||
|
||||
ParameterExpression pe = Expression.Parameter(source.ElementType, String.Empty);
|
||||
source = CreateSortQueryable(source, pe, Direction, DataField, false /* isThenBy */);
|
||||
|
||||
foreach (ThenBy thenBy in ThenByExpressions) {
|
||||
source = CreateSortQueryable(source, pe, thenBy.Direction, thenBy.DataField, true /* isThenBy */);
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
private static IQueryable CreateSortQueryable(IQueryable source, ParameterExpression parameterExpression, SortDirection direction, string dataField, bool isThenBy) {
|
||||
string methodName = isThenBy ? GetThenBySortMethod(direction) : GetSortMethod(direction);
|
||||
Expression propertyExpression = ExpressionHelper.CreatePropertyExpression(parameterExpression, dataField);
|
||||
|
||||
return source.Call(methodName,
|
||||
Expression.Lambda(propertyExpression, parameterExpression),
|
||||
source.ElementType,
|
||||
propertyExpression.Type);
|
||||
}
|
||||
|
||||
private static string GetSortMethod(SortDirection direction) {
|
||||
switch (direction) {
|
||||
case SortDirection.Ascending:
|
||||
return OrderByMethod;
|
||||
case SortDirection.Descending:
|
||||
return OrderDescendingByMethod;
|
||||
default:
|
||||
Debug.Fail("shouldn't get here!");
|
||||
return OrderByMethod;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetThenBySortMethod(SortDirection direction) {
|
||||
switch (direction) {
|
||||
case SortDirection.Ascending:
|
||||
return ThenByMethod;
|
||||
case SortDirection.Descending:
|
||||
return ThenDescendingByMethod;
|
||||
default:
|
||||
Debug.Fail("shouldn't get here!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq.Expressions;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
[
|
||||
PersistChildren(false),
|
||||
ParseChildren(true, "Parameters")
|
||||
]
|
||||
public abstract class ParameterDataSourceExpression : DataSourceExpression {
|
||||
private ParameterCollection _parameters;
|
||||
|
||||
[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
|
||||
public ParameterCollection Parameters {
|
||||
get {
|
||||
if (_parameters == null) {
|
||||
_parameters = new ParameterCollection();
|
||||
_parameters.ParametersChanged += new EventHandler(OnParametersChanged);
|
||||
}
|
||||
return _parameters;
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual IDictionary<string, object> GetValues() {
|
||||
return Parameters.ToDictionary(Context, Owner);
|
||||
}
|
||||
|
||||
public override void SetContext(Control owner, HttpContext context, IQueryableDataSource dataSource) {
|
||||
base.SetContext(owner, context, dataSource);
|
||||
|
||||
owner.Page.LoadComplete += new EventHandler(OnPageLoadComplete);
|
||||
}
|
||||
|
||||
private void OnParametersChanged(object sender, EventArgs e) {
|
||||
if (DataSource != null) {
|
||||
DataSource.RaiseViewChanged();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPageLoadComplete(object sender, System.EventArgs e) {
|
||||
Parameters.UpdateValues(Context, Owner);
|
||||
}
|
||||
|
||||
protected override object SaveViewState() {
|
||||
Pair p = new Pair();
|
||||
p.First = base.SaveViewState();
|
||||
p.Second = DataSourceHelper.SaveViewState(_parameters);
|
||||
return p;
|
||||
}
|
||||
|
||||
protected override void LoadViewState(object savedState) {
|
||||
Pair p = (Pair)savedState;
|
||||
base.LoadViewState(p.First);
|
||||
if (p.Second != null) {
|
||||
((IStateManager)Parameters).LoadViewState(p.Second);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void TrackViewState() {
|
||||
base.TrackViewState();
|
||||
DataSourceHelper.TrackViewState(_parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Permissions;
|
||||
using System.Web.UI;
|
||||
using System.Linq.Expressions;
|
||||
using System.Linq;
|
||||
|
||||
public class PropertyExpression : ParameterDataSourceExpression {
|
||||
public override IQueryable GetQueryable(IQueryable source) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
IDictionary<string, object> values = GetValues();
|
||||
List<Expression> equalsExpressions = new List<Expression>();
|
||||
ParameterExpression parameterExpression = Expression.Parameter(source.ElementType, String.Empty);
|
||||
|
||||
foreach (KeyValuePair<string, object> pair in values) {
|
||||
if (!String.IsNullOrEmpty(pair.Key)) {
|
||||
// Create the property expression
|
||||
Expression property = ExpressionHelper.CreatePropertyExpression(parameterExpression, pair.Key);
|
||||
// Get the value
|
||||
object value = ExpressionHelper.BuildObjectValue(pair.Value, property.Type);
|
||||
// Create Property == Value and '&&' the expressions together
|
||||
if (value != null) {
|
||||
Expression valueExpression = Expression.Constant(value, property.Type);
|
||||
Expression equalsExpression = Expression.Equal(property, valueExpression);
|
||||
equalsExpressions.Add(equalsExpression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (equalsExpressions.Any()) {
|
||||
Expression body = ExpressionHelper.And(equalsExpressions);
|
||||
return ExpressionHelper.Where(source, Expression.Lambda(body, parameterExpression));
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Web;
|
||||
using System.Web.UI;
|
||||
|
||||
[
|
||||
ParseChildren(true, "Expressions"),
|
||||
PersistChildren(false)
|
||||
]
|
||||
public class QueryExpression {
|
||||
private HttpContext _context;
|
||||
private Control _owner;
|
||||
private IQueryableDataSource _dataSource;
|
||||
private DataSourceExpressionCollection _expressions;
|
||||
|
||||
[
|
||||
PersistenceMode(PersistenceMode.InnerDefaultProperty)
|
||||
]
|
||||
public DataSourceExpressionCollection Expressions {
|
||||
get {
|
||||
if (_expressions == null) {
|
||||
_expressions = new DataSourceExpressionCollection();
|
||||
}
|
||||
return _expressions;
|
||||
}
|
||||
}
|
||||
|
||||
public void Initialize(Control owner, HttpContext context, IQueryableDataSource dataSource) {
|
||||
_owner = owner;
|
||||
_context = context;
|
||||
_dataSource = dataSource;
|
||||
|
||||
Expressions.SetContext(owner, context, dataSource);
|
||||
}
|
||||
|
||||
public virtual IQueryable GetQueryable(IQueryable source) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (DataSourceExpression e in Expressions) {
|
||||
source = e.GetQueryable(source) ?? source;
|
||||
}
|
||||
|
||||
return source;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Web.Resources;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
public class RangeExpression : ParameterDataSourceExpression {
|
||||
public string DataField {
|
||||
get {
|
||||
return (string)ViewState["DataField"] ?? String.Empty;
|
||||
}
|
||||
set {
|
||||
ViewState["DataField"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public RangeType MinType {
|
||||
get {
|
||||
object o = ViewState["MinType"];
|
||||
return o != null ? (RangeType)o : RangeType.None;
|
||||
}
|
||||
set {
|
||||
ViewState["MinType"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public RangeType MaxType {
|
||||
get {
|
||||
object o = ViewState["MaxType"];
|
||||
return o != null ? (RangeType)o : RangeType.None;
|
||||
}
|
||||
set {
|
||||
ViewState["MaxType"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
internal virtual new IOrderedDictionary GetValues() {
|
||||
return Parameters.GetValues(Context, Owner);
|
||||
}
|
||||
|
||||
public override IQueryable GetQueryable(IQueryable source) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (String.IsNullOrEmpty(DataField)) {
|
||||
throw new InvalidOperationException(AtlasWeb.Expressions_DataFieldRequired);
|
||||
}
|
||||
|
||||
IOrderedDictionary values = GetValues();
|
||||
ParameterExpression parameterExpression = Expression.Parameter(source.ElementType, String.Empty);
|
||||
Expression properyExpression = ExpressionHelper.GetValue(ExpressionHelper.CreatePropertyExpression(parameterExpression, DataField));
|
||||
|
||||
if (MinType == RangeType.None && MaxType == RangeType.None) {
|
||||
throw new InvalidOperationException(AtlasWeb.RangeExpression_RangeTypeMustBeSpecified);
|
||||
}
|
||||
|
||||
Expression minExpression = null;
|
||||
Expression maxExpression = null;
|
||||
|
||||
if (MinType != RangeType.None) {
|
||||
if (values.Count == 0) {
|
||||
throw new InvalidOperationException(AtlasWeb.RangeExpression_MinimumValueRequired);
|
||||
}
|
||||
|
||||
if (values[0] != null) {
|
||||
minExpression = GetMinRangeExpression(properyExpression, values[0], MinType);
|
||||
}
|
||||
}
|
||||
|
||||
if (MaxType != RangeType.None) {
|
||||
if (values.Count == 0 || ((minExpression != null) && (values.Count == 1))) {
|
||||
throw new InvalidOperationException(AtlasWeb.RangeExpression_MaximumValueRequired);
|
||||
}
|
||||
|
||||
object maxValue = minExpression == null ? values[0] : values[1];
|
||||
if (maxValue != null) {
|
||||
maxExpression = GetMaxRangeExpression(properyExpression, maxValue, MaxType);
|
||||
}
|
||||
}
|
||||
|
||||
if ((maxExpression == null) && (minExpression == null)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Expression rangeExpression = CreateRangeExpressionBody(minExpression, maxExpression);
|
||||
|
||||
return ExpressionHelper.Where(source, Expression.Lambda(rangeExpression, parameterExpression));
|
||||
}
|
||||
|
||||
private static Expression GetMinRangeExpression(Expression propertyExpression, object value, RangeType rangeType) {
|
||||
ConstantExpression constantValue = Expression.Constant(ExpressionHelper.BuildObjectValue(value, propertyExpression.Type));
|
||||
switch (rangeType) {
|
||||
case RangeType.Exclusive:
|
||||
return Expression.GreaterThan(propertyExpression, constantValue);
|
||||
case RangeType.None:
|
||||
return null;
|
||||
case RangeType.Inclusive:
|
||||
return Expression.GreaterThanOrEqual(propertyExpression, constantValue);
|
||||
default:
|
||||
Debug.Fail("shouldn't get here!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Expression GetMaxRangeExpression(Expression propertyExpression, object value, RangeType rangeType) {
|
||||
ConstantExpression constantValue = Expression.Constant(ExpressionHelper.BuildObjectValue(value, propertyExpression.Type));
|
||||
switch (rangeType) {
|
||||
case RangeType.Exclusive:
|
||||
return Expression.LessThan(propertyExpression, constantValue);
|
||||
case RangeType.None:
|
||||
return null;
|
||||
case RangeType.Inclusive:
|
||||
return Expression.LessThanOrEqual(propertyExpression, constantValue);
|
||||
default:
|
||||
Debug.Fail("shouldn't get here!");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Expression CreateRangeExpressionBody(Expression minExpression, Expression maxExpression) {
|
||||
if (minExpression == null && maxExpression == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (minExpression == null) {
|
||||
return maxExpression;
|
||||
}
|
||||
|
||||
if (maxExpression == null) {
|
||||
return minExpression;
|
||||
}
|
||||
|
||||
return Expression.AndAlso(minExpression, maxExpression);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System;
|
||||
|
||||
public enum RangeType {
|
||||
None,
|
||||
Exclusive,
|
||||
Inclusive
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Web.Resources;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
|
||||
public class SearchExpression : ParameterDataSourceExpression {
|
||||
public string DataFields {
|
||||
get {
|
||||
return (string)ViewState["DataFields"] ?? String.Empty;
|
||||
}
|
||||
set {
|
||||
ViewState["DataFields"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public SearchType SearchType {
|
||||
get {
|
||||
object o = ViewState["SearchType"];
|
||||
return o != null ? (SearchType)o : SearchType.StartsWith;
|
||||
}
|
||||
set {
|
||||
ViewState["SearchType"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public StringComparison ComparisonType {
|
||||
get {
|
||||
object o = ViewState["ComparisonType"];
|
||||
return o != null ? (StringComparison)o : StringComparison.OrdinalIgnoreCase;
|
||||
}
|
||||
set {
|
||||
ViewState["ComparisonType"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override IQueryable GetQueryable(IQueryable source) {
|
||||
if (source == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ((DataFields == null) || String.IsNullOrEmpty(DataFields.Trim())) {
|
||||
throw new InvalidOperationException(AtlasWeb.Expressions_DataFieldRequired);
|
||||
}
|
||||
|
||||
IDictionary<string, object> values = GetValues();
|
||||
|
||||
if (values.Count == 0) {
|
||||
throw new InvalidOperationException(AtlasWeb.SearchExpression_ParameterRequired);
|
||||
}
|
||||
|
||||
string query = Convert.ToString(values.First().Value, CultureInfo.CurrentCulture);
|
||||
|
||||
if (String.IsNullOrEmpty(query)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
string[] properties = DataFields.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
// Use the or expression to or the fields together
|
||||
List<Expression> searchExpressions = new List<Expression>();
|
||||
|
||||
ParameterExpression parameterExpression = Expression.Parameter(source.ElementType, String.Empty);
|
||||
|
||||
foreach (string p in properties) {
|
||||
Expression property = ExpressionHelper.CreatePropertyExpression(parameterExpression, p.Trim());
|
||||
searchExpressions.Add(CreateCallExpression(property, query));
|
||||
}
|
||||
|
||||
return ExpressionHelper.Where(source,
|
||||
Expression.Lambda(ExpressionHelper.Or(searchExpressions),
|
||||
parameterExpression));
|
||||
}
|
||||
|
||||
private Expression CreateCallExpression(Expression property, string query) {
|
||||
// LINQ to SQL does not support the overloads StartsWith(string, StringComparer) or EndsWith(string, StringComparer)
|
||||
// and Contains has not overload that takes a StringComparer
|
||||
if (SearchType == SearchType.Contains || (ViewState["ComparisonType"] == null)) {
|
||||
return Expression.Call(property, SearchType.ToString(), Type.EmptyTypes, Expression.Constant(query, property.Type));
|
||||
}
|
||||
return Expression.Call(property, SearchType.ToString(), Type.EmptyTypes, Expression.Constant(query, property.Type), Expression.Constant(ComparisonType));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System;
|
||||
|
||||
public enum SearchType {
|
||||
Contains,
|
||||
StartsWith,
|
||||
EndsWith
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace System.Web.UI.WebControls.Expressions {
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Security.Permissions;
|
||||
|
||||
public class ThenBy {
|
||||
public string DataField {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public SortDirection Direction {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user