Todas las entradas por César Castro Cuba

Dynamic SQL-like Linq OrderBy Extension

Dynamic SQL-like Linq OrderBy Extension

Anyway, hope someone finds it useful. And if you see any areas that could use some TLC please let me know A
Posted by Adam Anderson at 7:48 PM  

http://aonnull.blogspot.com/2010/08/dynamic-sql-like-linq-orderby-extension.html

So, it’s been a while, but I thought I take moment and do my annual blog post ;).

I’ve been playing around with ASP.NET MVC and the Linq stuff for NHibernate recently. I was in need of an OrderBy extension method that could take a SQL-Like OrderBy string and sort a IQueryable<> or IEnumerable<> collection. I wrote up an implementation that worked, but I just wasn’t satisfied with its internals (quite a bit of reflection to get the correct type to construct a LambdaExpression, etc)

At any rate, I couldn’t leave well enough alone, and, after a bit of Googling, I ran across this StackOverflow answer aboutDynamic LINQ OrderBy. The extension method wasn’t exactly what I was looking for, but that ApplyOrder method is slick, and solved the portion of my implementation that was bothering me.

So, I though I would post up my version in case anybody finds it useful. It handles the following inputs:

list.OrderBy("SomeProperty");
list.OrderBy("SomeProperty DESC");
list.OrderBy("SomeProperty DESC, SomeOtherProperty");
list.OrderBy("SomeSubObject.SomeProperty ASC, SomeOtherProperty DESC");

Dynamic SQL-like Linq OrderBy Extension

    public static class OrderByHelper
{
public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> enumerable, string orderBy)
{
return enumerable.AsQueryable().OrderBy(orderBy).AsEnumerable();
}public static IQueryable<T> OrderBy<T>(this IQueryable<T> collection, string orderBy)
{
foreach(OrderByInfo orderByInfo in ParseOrderBy(orderBy))
collection = ApplyOrderBy<T>(collection, orderByInfo);return collection;
}private static IQueryable<T> ApplyOrderBy<T>(IQueryable<T> collection, OrderByInfo orderByInfo)
{
string[] props = orderByInfo.PropertyName.Split(‘.’);
Type type = typeof(T);ParameterExpression arg = Expression.Parameter(type, «x»);
Expression expr = arg;
foreach (string prop in props)
{
// use reflection (not ComponentModel) to mirror LINQ
PropertyInfo pi = type.GetProperty(prop);
expr = Expression.Property(expr, pi);
type = pi.PropertyType;
}
Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);
LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);
string methodName = String.Empty;

if (!orderByInfo.Initial && collection is IOrderedQueryable<T>)
{
if (orderByInfo.Direction == SortDirection.Ascending)
methodName = «ThenBy»;
else
methodName = «ThenByDescending»;
}
else
{
if (orderByInfo.Direction == SortDirection.Ascending)
methodName = «OrderBy»;
else
methodName = «OrderByDescending»;
}

//TODO: apply caching to the generic methodsinfos?
return (IOrderedQueryable<T>)typeof(Queryable).GetMethods().Single(
method => method.Name == methodName
&& method.IsGenericMethodDefinition
&& method.GetGenericArguments().Length == 2
&& method.GetParameters().Length == 2)
.MakeGenericMethod(typeof(T), type)
.Invoke(null, new object[] { collection, lambda });

}

private static IEnumerable<OrderByInfo> ParseOrderBy(string orderBy)
{
if (String.IsNullOrEmpty(orderBy))
yield break;

string[] items = orderBy.Split(‘,’);
bool initial = true;
foreach(string item in items)
{
string[] pair = item.Trim().Split(‘ ‘);

if (pair.Length > 2)
throw new ArgumentException(String.Format(«Invalid OrderBy string ‘{0}’. Order By Format: Property, Property2 ASC, Property2 DESC»,item));

string prop = pair[0].Trim();

if(String.IsNullOrEmpty(prop))
throw new ArgumentException(«Invalid Property. Order By Format: Property, Property2 ASC, Property2 DESC»);

SortDirection dir = SortDirection.Ascending;

if (pair.Length == 2)
dir = («desc».Equals(pair[1].Trim(), StringComparison.OrdinalIgnoreCase) ? SortDirection.Descending : SortDirection.Ascending);

yield return new OrderByInfo() { PropertyName = prop, Direction = dir, Initial = initial };

initial = false;
}

}

private class OrderByInfo
{
public string PropertyName { get; set; }
public SortDirection Direction { get; set; }
public bool Initial { get; set; }
}

private enum SortDirection
{
Ascending = 0,
Descending = 1
}
}

The Reactive Extensions (Rx)…

…is a library to compose asynchronous and event-based programs using observable collections and LINQ-style query operators.

About the Reactive Extensions

The Reactive Extensions (Rx) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators. Using Rx, developers represent asynchronous data streams with Observablesquery asynchronous data streams using LINQ operators, andparameterize the concurrency in the asynchronous data streams using Schedulers. Simply put, Rx = Observables + LINQ + Schedulers.

Whether you are authoring a traditional desktop or web-based application, you have to deal with asynchronous and event-based programming from time to time. Desktop applications have I/O operations and computationally expensive tasks that might take a long time to complete and potentially block other active threads. Furthermore, handling exceptions, cancellation, and synchronization is difficult and error-prone.

Using Rx, you can represent multiple asynchronous data streams (that come from diverse sources, e.g., stock quote, tweets, computer events, web service requests, etc.), and subscribe to the event stream using the IObserver<T> interface. The IObservable<T> interface notifies the subscribed IObserver<T> interface whenever an event occurs.

Because observable sequences are data streams, you can query them using standard LINQ query operators implemented by the Observable type. Thus you can filter, project, aggregate, compose and perform time-based operations on multiple events easily by using these static LINQ operators. In addition, there are a number of other reactive stream specific operators that allow powerful queries to be written. Cancellation, exceptions, and synchronization are also handled gracefully by using the extension methods provided by Rx.

WCF Endpoint Address and Samples

http://forums.silverlight.net/t/20767.aspx/1
http://msdn.microsoft.com/en-us/library/ms733749.aspx
http://social.msdn.microsoft.com/forums/en-US/asmxandxml/thread/b001fef4-1d24-44b1-b24f-6738916e6ca2
http://stackoverflow.com/questions/5261810/multiple-endpoint-with-multiple-contracts-in-wcf
http://geeks.netindonesia.net/blogs/ferry/archive/2007/05/17/WCF-ServiceHost-_2D00_-Single-contract-multiple-endpoints.aspx
http://msdn.microsoft.com/en-us/library/ms752238(v=vs.90).aspx
http://msdn.microsoft.com/en-us/library/ms752258(v=vs.90).aspx
http://msdn.microsoft.com/en-us/library/ms752036(v=vs.90).aspx
http://social.msdn.microsoft.com/Forums/en-US/windowsazuremanagement/thread/d5219181-321f-452f-99fc-b1407c2023d0/
http://geeks.ms/blogs/cgonzalez/archive/2009/07/06/servicios-wcf-hospedados-en-iis-i.aspx

WCF Username and Password (Security) && (Membership)

http://stackoverflow.com/questions/563037/wcf-authentication-with-custom-clientcredentials-what-is-the-clientcredentialtyp

http://www.devatwork.nl/2007/05/wcf-username-authentication/

http://blogs.msdn.com/b/sonuarora/archive/2007/04/21/setting-client-credentials.aspx

http://blogs.msdn.com/b/pedram/archive/2007/10/05/wcf-authentication-custom-username-and-password-validator.aspx

http://msdn.microsoft.com/es-es/library/system.servicemodel.description.clientcredentials.username.aspx

http://burcakcakiroglu.com/?p=2113

http://www.dotnetcurry.com/ShowArticle.aspx?ID=589

http://www.dotnetcurry.com/ShowArticle.aspx?ID=624

Automatic Updater

http://appupdater.codeplex.com/releases/view/36518

http://windowsclient.net/articles/appupdater.aspx 

http://msdn.microsoft.com/en-us/library/aa969776.aspx

http://stackoverflow.com/questions/3749183/automatic-update

http://blogs.msdn.com/b/dotnetinterop/archive/2008/03/28/simple-auto-update-for-wpf-apps.aspx

http://www.codeproject.com/KB/install/DDayUpdate_Part1.aspx

http://wyday.com/wybuild/help/automatic-updates/using-automatic-updater-in-wpf.php

http://wyday.com/forum/viewtopic.php?f=1&t=570

http://stackoverflow.com/questions/1609957/how-can-a-net-program-update-itself

http://social.msdn.microsoft.com/Forums/ar/winformssetup/thread/1c7cdf0d-f543-44dd-9b92-4f7b3a9bc8e0

http://social.msdn.microsoft.com/forums/en-US/wpf/thread/d8ee7275-4801-4a34-8254-e8d381ca1a6a

 

Expression Tree Serialization

http://archive.msdn.microsoft.com/exprserialization

Overview

The sample includes these components:

  1. An Expression Tree serialization API: A general purpose XML serialization of Expression Trees. This should work over any expression tree – though there are inevitably bugs. The serialization format is fairly crude, but has been expressive enough to support the variety of expression trees I’ve tried throwing at it.
  2. A wrapper for serializing/deserializing LINQ to SQL queries: A wrapper around the expression serializer allows serializing LINQ to SQL queries and de-serializing into a query against a given DataContext.
  3. A WCF service which accepts serialized query expression trees and executes against a back-end LINQ to SQL: To enable querying across tiers, a WCF service exposes service methods which execute serialized queries. The service implementation deserializes the queries against its LINQ to SQL connection.
  4. An IQueryable implementation wrapping the client side of the WCF service: The client-side calling syntax is simplified by providing an IQueryable implementation. This implementation, RemoteTable, executes queries by serializing the query expression tree and calling the appropriate service. The object model that the service user is able to query against is imported by the WCF service reference per the DataContracts on the LINQ to SQL mapping on the server side.