/// <summary> /// <see cref="Microsoft.Samples.NLayerApp.Domain.Core.IRepository{TEntity}"/> /// </summary> /// <param name="pageIndex"><see cref="Microsoft.Samples.NLayerApp.Domain.Core.IRepository{TEntity}"/></param> /// <param name="pageCount"><see cref="Microsoft.Samples.NLayerApp.Domain.Core.IRepository{TEntity}"/></param> /// <param name="orderByExpression"><see cref="Microsoft.Samples.NLayerApp.Domain.Core.IRepository{TEntity}"/></param> /// <param name="ascending"><see cref="Microsoft.Samples.NLayerApp.Domain.Core.IRepository{TEntity}"/></param> /// <returns><see cref="Microsoft.Samples.NLayerApp.Domain.Core.IRepository{TEntity}"/></returns> public virtual IEnumerable <TEntity> GetPagedElements <S>(int pageIndex, int pageCount, System.Linq.Expressions.Expression <Func <TEntity, S> > orderByExpression, bool ascending) { //checking arguments for this query if (pageIndex < 0) { throw new ArgumentException(Resources.Messages.exception_InvalidPageIndex, "pageIndex"); } if (pageCount <= 0) { throw new ArgumentException(Resources.Messages.exception_InvalidPageCount, "pageCount"); } if (orderByExpression == (Expression <Func <TEntity, S> >)null) { throw new ArgumentNullException("orderByExpression", Resources.Messages.exception_OrderByExpressionCannotBeNull); } _TraceManager.TraceInfo( string.Format(CultureInfo.InvariantCulture, Resources.Messages.trace_GetPagedElementsRepository, typeof(TEntity).Name, pageIndex, pageCount, orderByExpression.ToString())); //Create associated IObjectSet and perform query IObjectSet <TEntity> objectSet = CreateSet(); return(objectSet.Paginate <TEntity, S>(orderByExpression, pageIndex, pageCount, ascending)); }
/// <summary> /// Gets the property info as a result of the property at the end of a lambda expression. /// </summary> /// <typeparam name="TSource"></typeparam> /// <typeparam name="TProperty"></typeparam> /// <param name="source">The source object instance.</param> /// <param name="propertyLambda">The lamda expression.</param> /// <returns></returns> public static PropertyInfo PropertyInfo <TSource, TProperty>(this TSource source, System.Linq.Expressions.Expression <Func <TSource, TProperty> > propertyLambda) { Type type = typeof(TSource); MemberExpression member = propertyLambda.Body as MemberExpression; if (member == null) { throw new ArgumentException(string.Format( "Expression '{0}' refers to a method, not a property.", propertyLambda.ToString())); } PropertyInfo propInfo = member.Member as PropertyInfo; if (propInfo == null) { throw new ArgumentException(string.Format( "Expression '{0}' refers to a field, not a property.", propertyLambda.ToString())); } return(propInfo); }
public void Prueba() { System.Linq.Expressions.Expression <Func <Paciente, bool> > oExpr = (x) => (x.Id != 3) || (x.Id == 3 && x.Id < 4); string sTesto = oExpr.ToString(); //var sR = Conversion(sTesto); var sResult = "((MayorEdad = 1) AND (Id = 3) OR (Nombre LIKE N'%a'))"; string sRegex = "(\b[a-z])"; int i = 0; string sQuery = sResult.Replace(sRegex, "({" + (i++) + "})"); Assert.IsTrue(sResult == "((MayorEdad = 1) AND (Id = 3) OR (Nombre LIKE N'%a'))"); }
public IQueryable <T> LoadEntities(System.Linq.Expressions.Expression <Func <T, bool> > lambdaWehre) { IQueryable <T> result = null; log.DebugFormat("查询: FullName:{0} lambdaWehre:{1}", typeof(T).FullName, lambdaWehre.ToString()); try { result = LoadEntitie(lambdaWehre); log.DebugFormat("查询 FullName:{0} lambdaWehre:{1} linq:{2}", typeof(T).FullName, lambdaWehre.ToString(), result.ToString().Replace("\r\n", "")); log.Debug("查询结果: " + JsonHelper.ObjectToJson(result)); } catch (Exception ex) { log.ErrorFormat("查询异常 FullName:{0} lambdaWehre:{1} ex:{2}", typeof(T).FullName, lambdaWehre.ToString(), ex); } return(result); }
public virtual IList <T> List(System.Linq.Expressions.Expression <Func <T, bool> > predicate) { if (enable) { key = key + predicate.ToString(); if (_distributedCache.Get(key) == null) { _distributedCache.Set(key, Object2Bytes(_dbContext.Set <T>() .Where(predicate) .ToList()), new DistributedCacheEntryOptions()); } } else { return(_dbContext.Set <T>().Where(predicate).ToList()); } return((IList <T>)Bytes2Object(_distributedCache.Get(key))); }
/// <summary> /// <see cref="Domain.Core.IRepository{TEntity}"/> /// </summary> /// <typeparam name="K"><see cref="Domain.Core.IRepository{TEntity}"/></typeparam> /// <typeparam name="S"><see cref="Domain.Core.IRepository{TEntity}"/></typeparam> /// <param name="pageIndex"><see cref="Domain.Core.IRepository{TEntity}"/></param> /// <param name="pageCount"><see cref="Domain.Core.IRepository{TEntity}"/></param> /// <param name="orderByExpression"><see cref="Domain.Core.IRepository{TEntity}"/></param> /// <param name="ascending"><see cref="Domain.Core.IRepository{TEntity}"/></param> /// <returns><see cref="Domain.Core.IRepository{TEntity}"/></returns> public virtual IEnumerable <K> GetPagedElements <K, S>(int pageIndex, int pageCount, System.Linq.Expressions.Expression <Func <K, S> > orderByExpression, bool ascending) where K : TEntity { //checking query arguments if (pageIndex < 0) { throw new ArgumentException(Resources.Messages.exception_InvalidPageIndex, "pageIndex"); } if (pageCount <= 0) { throw new ArgumentException(Resources.Messages.exception_InvalidPageCount, "pageCount"); } if (orderByExpression == (Expression <Func <K, S> >)null) { throw new ArgumentNullException("orderByExpression", Resources.Messages.exception_OrderByExpressionCannotBeNull); } _TraceManager.TraceInfo( string.Format(CultureInfo.InvariantCulture, Resources.Messages.trace_GetPagedElementsRepository, typeof(K).Name, pageIndex, pageCount, orderByExpression.ToString())); //Create IObjectSet for this type and perform query IObjectSet <TEntity> objectSet = _CurrentUoW.CreateSet <TEntity>(); return((ascending) ? objectSet.OfType <K>() .OrderBy(orderByExpression) .Skip(pageIndex * pageCount) .Take(pageCount) .ToList() : objectSet.OfType <K>() .OrderByDescending(orderByExpression) .Skip(pageIndex * pageCount) .Take(pageCount) .ToList()); }
/// <summary> /// Query function returning results and count control /// </summary> private IEnumerable <TData> Query(System.Linq.Expressions.Expression <Func <TData, bool> > query, int offset, int?count, out int totalResults, Guid queryId, bool countResults, bool fastQuery, IEnumerable <String> expandProperties = null) { if (query == null) { throw new ArgumentNullException(nameof(query)); } DataQueryPreEventArgs <TData> preArgs = new DataQueryPreEventArgs <TData>(query, offset, count); this.Querying?.Invoke(this, preArgs); if (preArgs.Cancel) { this.m_tracer.TraceWarning("Pre-Event handler indicates abort query {0}", query); totalResults = preArgs.TotalResults; return(preArgs.Results); } #if PERFMON Stopwatch sw = new Stopwatch(); sw.Start(); #endif // Query object using (var context = this.CreateReadonlyConnection()) try { IEnumerable <TData> results = null; using (context.LockConnection()) { this.m_tracer.TraceVerbose("QUERY {0}", query); if (fastQuery) { context.DelayLoadMode = LoadState.PartialLoad; } else { context.DelayLoadMode = LoadState.FullLoad; } if (expandProperties != null) { context.LoadAssociations = expandProperties.ToArray(); } results = this.Query(context, query, offset, count ?? -1, out totalResults, queryId, countResults); } var postData = new DataQueryResultEventArgs <TData>(query, results, offset, count, totalResults); this.Queried?.Invoke(this, postData); totalResults = postData.TotalResults; // Remove from the cache foreach (var itm in context.CacheOnCommit.AsParallel()) { ApplicationContext.Current.GetService <IDataCachingService>()?.Add(itm); } return(postData.Results); } catch (NotSupportedException e) { this.m_tracer.TraceVerbose("Cannot perform LINQ query, switching to stored query sqp_{0}", typeof(TData).Name, e); // Build dictionary var httpValues = QueryExpressionBuilder.BuildQuery <TData>(query, true); var filter = new Dictionary <String, Object>(); foreach (var f in httpValues) { object existing = null; if (filter.TryGetValue(f.Key, out existing)) { if (!(existing is IList)) { existing = new List <Object>() { existing }; filter[f.Key] = existing; } (existing as IList).Add(f.Value); } else { filter.Add(f.Key, f.Value); } } // Query return(this.Query(String.Format("sqp_{0}", typeof(TData).Name), filter, offset, count, out totalResults, queryId)); } catch (Exception e) { this.m_tracer.TraceError("Error : {0}", e); throw; } #if PERFMON finally { sw.Stop(); ApplicationContext.Current.PerformanceLog(typeof(TData).Name, nameof(Query), query.ToString(), sw.Elapsed); } #endif }
public static void Main() { TestClass test = new TestClass(); // Executing a method directly is pretty straight forward. // What if we don't want to execute these methods now, // but want to execute them when some event occurs? // This is where delegates come in. ImSpeakingNow("How are you?"); MathMethods.MathSpeaks("I'm doing fine"); // How did we get from methods to delegates to lambdas? How are they related? // We use delegates to reference any method that has a specific signature. // As long as the signatures match, we can reference any method // and execute it using the delegate. // Once upon a time you would create a delegate using object constructor syntax. // This creates a reference to a method, which can be executed at any time. SpeakDelegate me = new SpeakDelegate(ImSpeakingNow); SpeakDelegate math = new SpeakDelegate(MathMethods.MathSpeaks); Action <string, int> xxx = MathMethods.NewMethod; xxx("hello", 9); Action <string, int[]> newAction = MathMethods.NewMethod2; int[] myints = new int[] { 9, 8, 7 }; newAction("I an another action", myints); Func <string, int, int> myFunc = MathMethods.myFunc; myFunc += MathMethods.myFunc2; int length = myFunc("Paul", 60); // Now execute the method you're referencing using the delegate it's mapped to. me("What a sunny day"); math("I like to count"); // Using the object constructor syntax was a little cumbersome, so // "implied conversion" was introduced. The compiler knows that // the method "TalkingTest" has the same signature as the SpeakDelegate // so it performs all the heavy lifting under the covers and allows // you to simply assign a method to a delegate. SpeakDelegate abc = test.TalkingTest; abc("I'm new"); me = test.TalkingTest; // A Multicast Delegate is a delegate that holds the references of more than one function. // When a multicast delegate is executed, then all the functions which are referenced by // the delegate are going to be executed. me += ImSpeakingNow; me += MathMethods.MathSpeaks; // Notice that all 3 methods that this deletate references are executed with one line of code. // Also notice that all 3 methods are called synchronously! me("We're speaking the same language"); // Example of passing a delegate as a parameter to a method ILikeDelegates(me, "All my delegates should say this"); ILikeDelegates(ImSpeakingNow, "All my delegates should say this"); // We can remove method references from the delegate to have as few or as many // references in the delegate that we want. me -= ImSpeakingNow; me -= MathMethods.MathSpeaks; me("Just me now"); // Here are a couple more examples of using delegates MathMethods.DoMathDelegate doMath = test.AddThese; int Total = doMath(4, 8); Console.WriteLine($"Total of 4+8 = {Total}"); // An "Action" is a predefined delegate that takes 0 or more parameters, does SOMETHING and returns void. // An Action can take no parameter or Action someAction = test.DoSomething; someAction(); // Events help implement the "publisher/subscriber" model. // Any object can publish a set of events to which other objects can subscribe. // Let's say that we want to be notified whenever a method in the // TestClass class completes. That class has an event called OperationCompleteEvent // that is fired to tell anyone listening about that event. test.OperationCompleteEvent += OnOperationComplete; // Now that our event has been hooked up, let's execute the same // code as before, but this time the events will fire and we will // be notified by having our event handlers called. doMath(4, 8); someAction(); // Don't want to be notified of these events anymore test.OperationCompleteEvent -= OnOperationComplete; // There are many times when we want to execute code in some method // but it will only ever be called in one place. It seems like a // real waste to have to declare a method like we did // with "ImSpeakingNow(string SayThis)" just for that purpose. // To that end, the "Anonymous" method was created. // Anonymous methods provide a way to write unnamed inline // statement blocks that can be executed in a delegate invocation. List <String> names = new List <String>(); names.Add("Fred"); names.Add("Sam"); names.Add("Bob"); // The following demonstrates the anonymous method feature of C# // to display the contents of the list to the console names.ForEach(delegate(String name) { Console.WriteLine(name); }); me = delegate(string Something) { Console.WriteLine($"Anonymous says: {Something}"); }; me("I am here!"); // A lambda expression is nothing more than syntactic sugar for an anonymous method. // The following lambda expression is EXACTLY the same as the anonymous method above. // The type of the parameter "Something" is inferred by the compiler. me = (Something) => { Console.WriteLine($"Lambda says: {Something}"); }; me("I am here!"); Func <int, int, int> ReturnSomething = (x, y) => { return(x + y); }; int value = ReturnSomething(9, 8); Console.WriteLine($"Value is {value}"); // The signature of the method called is: // public static int Calculate(DoMathDelegate DoMath, int first, int second) // // The first parameter is a lambda expression matching the delegate signature: // public delegate int DoMathDelegate(int first, int second) // // The next 2 parameters are the values consumed by the DoMathDelegate Console.WriteLine($"Value is {MathMethods.Calculate((a, b) => a + b, 1, 2)} using lambda"); Console.WriteLine($"Value is {MathMethods.Calculate((x, z) => x * z, 1, 2)}"); Console.WriteLine($"Value is {MathMethods.Calculate((q, r) => q - r, 1, 2)}"); Console.WriteLine($"Value is {MathMethods.Calculate((f, h) => f / h, 1, 2)}"); // Parameter delegates are often designed to work on data that is internal to the class/type. // The delegate is typically used to iterate over the internal data values to // produce some kind of result or filter the data in some way. MathMethods.AppendValue(2); MathMethods.AppendValue(3); MathMethods.AppendValue(4); MathMethods.AppendValue(5); MathMethods.AppendValue(6); MathMethods.AppendValue(7); MathMethods.AppendValue(8); Console.WriteLine($"CalculateTotal addition is {MathMethods.CalculateTotal((a, b) => a + b)}"); Console.WriteLine($"CalculateTotal multiplication is {MathMethods.CalculateTotal((a, b) => a * b)}"); // Here we will create a lambda expression that will be used to filter out all even numbers List <int> even = MathMethods.RunFilter(i => i % 2 == 0); foreach (int x in even) { Console.WriteLine($"Even {x}"); } // Here we will create a lambda expression that will be used to filter out all odd numbers List <int> odd = MathMethods.RunFilter(i => i % 2 == 1); foreach (int x in odd) { Console.WriteLine($"Odd {x}"); } /// A Predicate is a delegate like the Func and Action delegates. /// It represents a method that checks whether the passed parameter meets a set of criteria. /// A predicate delegate methods must take one input parameter and return a boolean - true or false. /// You'll find that built in delegate types like "Action", "Func<>" and "Predicate<>" can be used /// instead of creating your own custom delegates most of the time. Here's an example of using /// a built-in "Predicate<int>" instead of custom "FilterDelegate". List <int> lessThan5 = MathMethods.RunFilterPredicate(i => i < 5); Console.WriteLine($"Values less than 5 using predicate"); foreach (int x in lessThan5) { Console.WriteLine($"{x}"); } //----------------- What's happening under the hood? Expression Trees! System.Linq.Expressions.Expression <Func <int, int> > myExpression = x => x * x; string lambdaString = myExpression.ToString(); Func <int, int> compiledDelegate = myExpression.Compile(); int parameter = 8; int answer = compiledDelegate(parameter); Console.WriteLine($"Result of calling '{lambdaString}' using parameter '{parameter}' is '{answer}'"); myExpression.DumpExpression(); Expression <Func <int, bool> > expr = i => i % 2 == 0; expr.DumpExpression(); Expression <Func <string, string, string> > tree = (a, b) => a.ToLower() + b.ToUpper(); tree.DumpExpression(); Expression <SpeakDelegate> myDelegate = (sayThis) => Console.WriteLine(sayThis); myDelegate.DumpExpression(); FilmCritic.DemonstrateDeferredExecution("Rambo", "First", new DateTime(2009, 1, 1)); List <string> listOfNames = new List <string>() { "John Doe", "Jane Doe", "Jenna Doe", "Joe Doe" }; // Query syntax IEnumerable <string> qNames = from name in listOfNames where name.Length <= 8 select name; // Method syntax var mNames = listOfNames.Where(name => name.Length <= 8); // Representation of the query Expression <Func <IEnumerable <string>, IEnumerable <string> > > lambda = (myList) => from name in myList where name.Length <= 8 select name; lambda.DumpExpression(); Console.WriteLine($"{lambda}"); // Compile and Execute the query var compiledLinq = lambda.Compile(); IEnumerable <string> expressionNames = compiledLinq(listOfNames); foreach (string x in expressionNames) { Console.WriteLine($"{x}"); } }
/// <summary> /// Query function returning results and count control /// </summary> private IEnumerable <TData> Query(System.Linq.Expressions.Expression <Func <TData, bool> > query, Guid?queryId, int offset, int?count, out int totalResults, bool countResults, bool fastQuery, IPrincipal principal, ModelSort <TData>[] orderBy) { if (query == null) { throw new ArgumentNullException(nameof(query)); } QueryRequestEventArgs <TData> preArgs = new QueryRequestEventArgs <TData>(query, offset, count, queryId, principal, orderBy); this.Querying?.Invoke(this, preArgs); if (preArgs.Cancel) { this.m_tracer.TraceWarning("Pre-Event handler indicates abort query {0}", query); totalResults = preArgs.TotalResults; return(preArgs.Results); } #if PERFMON Stopwatch sw = new Stopwatch(); sw.Start(); #endif // Query object using (var context = this.CreateReadonlyConnection(principal)) try { IEnumerable <TData> results = null; using (context.LockConnection()) { this.m_tracer.TraceVerbose("QUERY {0}", query); if (fastQuery) { context.DelayLoadMode = LoadState.PartialLoad; } else { context.DelayLoadMode = LoadState.FullLoad; } results = this.Query(context, query, queryId.GetValueOrDefault(), offset, count ?? -1, out totalResults, countResults, orderBy); } var postData = new QueryResultEventArgs <TData>(query, results, offset, count, totalResults, queryId, principal); this.Queried?.Invoke(this, postData); totalResults = postData.TotalResults; // Remove from the cache foreach (var itm in context.CacheOnCommit.AsParallel()) { ApplicationContext.Current.GetService <IDataCachingService>()?.Add(itm); } return(postData.Results); } catch (SQLiteException e) { this.m_tracer.TraceError("Error executing query {1} : {0}", e, context.Connection); throw new DataPersistenceException($"Data error executing query againt {typeof(TData)}", e); } catch (Exception e) { this.m_tracer.TraceError("Error : {0}", e); throw new DataPersistenceException($"Error executing query against {typeof(TData)}", e); } #if PERFMON finally { sw.Stop(); ApplicationContext.Current.PerformanceLog(typeof(TData).Name, nameof(Query), query.ToString(), sw.Elapsed); } #endif }