Go to the documentation of this file.00001 using System;
00002 using System.Linq;
00003 using System.Linq.Expressions;
00004 using N2.Details;
00005
00006 namespace N2.Linq
00007 {
00008 public static class QueryableExtensions
00009 {
00010 public static IQueryable<T> WhereDetail<T>(this IQueryable<T> query, Expression<Func<T, bool>> expr) where T : ContentItem
00011 {
00012 if (query.Provider is ContentQueryProvider)
00013 ((ContentQueryProvider)query.Provider).WhereDetailExpressions[expr] = true;
00014 return query.Where(expr);
00015 }
00016
00017 public static IQueryable<T> WhereDetailEquals<T, TValue>(this IQueryable<T> query, TValue value) where T : ContentItem
00018 {
00019 var queryByName = query.Where(
00020 StringComparison<T>(null, value as string)
00021 ?? ContentItemComparison<T>(null, value as ContentItem)
00022 ?? IntegerComparison<T>(null, value as int?)
00023 ?? DateTimeComparison<T>(null, value as DateTime?)
00024 ?? BooleanComparison<T>(null, value as bool?)
00025 ?? DoubleComparison<T>(null, value as double?)
00026 ?? UnknownValueType<T>(null, value));
00027
00028 return queryByName;
00029 }
00030
00031 public static IQueryable<T> WhereDetailEquals<T, TValue>(this IQueryable<T> query, string name, TValue value) where T : ContentItem
00032 {
00033 var queryByName = query.Where(
00034 StringComparison<T>(name, value as string)
00035 ?? ContentItemComparison<T>(name, value as ContentItem)
00036 ?? IntegerComparison<T>(name, value as int?)
00037 ?? DateTimeComparison<T>(name, value as DateTime?)
00038 ?? BooleanComparison<T>(name, value as bool?)
00039 ?? DoubleComparison<T>(name, value as double?)
00040 ?? UnknownValueType<T>(name, value));
00041
00042 return queryByName;
00043 }
00044
00045 private static Expression<Func<T, bool>> BooleanComparison<T>(string name, bool? value) where T : ContentItem
00046 {
00047 if (value == null)
00048 return null;
00049
00050 if (name == null) return (ci) => ci.Details.Values.OfType<BooleanDetail>().Any(cd => cd.BoolValue == value.Value);
00051 return (ci) => ci.Details.Values.OfType<BooleanDetail>().Any(cd => cd.Name == name && cd.BoolValue == value.Value);
00052 }
00053
00054 private static Expression<Func<T, bool>> IntegerComparison<T>(string name, int? value) where T : ContentItem
00055 {
00056 if (value == null)
00057 return null;
00058
00059 if (name == null) return (ci) => ci.Details.Values.OfType<IntegerDetail>().Any(cd => cd.Name == name && cd.IntValue == value.Value);
00060 return (ci) => ci.Details.Values.OfType<IntegerDetail>().Any(cd => cd.Name == name && cd.IntValue == value.Value);
00061 }
00062
00063 private static Expression<Func<T, bool>> DoubleComparison<T>(string name, double? value) where T : ContentItem
00064 {
00065 if (value == null)
00066 return null;
00067
00068 if (name == null) return (ci) => ci.Details.Values.OfType<DoubleDetail>().Any(cd => cd.DoubleValue == value.Value);
00069 return (ci) => ci.Details.Values.OfType<DoubleDetail>().Any(cd => cd.Name == name && cd.DoubleValue == value.Value);
00070 }
00071
00072 private static Expression<Func<T, bool>> DateTimeComparison<T>(string name, DateTime? value) where T : ContentItem
00073 {
00074 if (value == null)
00075 return null;
00076
00077 if (name == null) return (ci) => ci.Details.Values.OfType<DateTimeDetail>().Any(cd => cd.DateTimeValue == value.Value);
00078 return (ci) => ci.Details.Values.OfType<DateTimeDetail>().Any(cd => cd.Name == name && cd.DateTimeValue == value.Value);
00079 }
00080
00081 private static Expression<Func<T, bool>> StringComparison<T>(string name, string value) where T : ContentItem
00082 {
00083 if (value == null)
00084 return null;
00085
00086 if (name == null) return (ci) => ci.Details.Values.OfType<StringDetail>().Any(cd => cd.StringValue == value);
00087 return (ci) => ci.Details.Values.OfType<StringDetail>().Any(cd => cd.Name == name && cd.StringValue == value);
00088 }
00089
00090 private static Expression<Func<T, bool>> ContentItemComparison<T>(string name, ContentItem value) where T : ContentItem
00091 {
00092 if (value == null)
00093 return null;
00094
00095 if (name == null) return (ci) => ci.Details.Values.OfType<LinkDetail>().Any(cd => cd.Name == name && cd.LinkedItem == value);
00096 return (ci) => ci.Details.Values.OfType<LinkDetail>().Any(cd => cd.Name == name && cd.LinkedItem == value);
00097 }
00098
00099 private static Expression<Func<T, bool>> UnknownValueType<T>(string name, object value) where T : ContentItem
00100 {
00101 throw new NotSupportedException(value + " is not supported.");
00102 }
00103 }
00104 }