April 2010 - Posts
Just took the 70-513 exam. Here are some thoughts:
- 84 questions
- 240 minutes total time
- Lots of questions on transactions
- Lots of questions on sessions and callbacks
- Some questions on scripting (jQuery)
- Some questions on throttling
- Absolutely no questions on interception
As for the other exams, I still don't know the result, but I think I may have passed...
I just created a mailing list for the discussion of NHibernate-related issues in portuguese: NHibernate Portugal. Feel free to join and share your experiences and knowledge!
Well, TechDays 2010 Portugal is over, time for a balance.
I really enjoyed being a speaker, although my presentation took a lot more time than it should, it was gratifying to see so many people staying until the end. Lots of subjects were left behind, though.
My presentation is available at my SkyDrive, here. Soon I will place there the source code, too.
I would like to know if you've been there, and, if so, what do you think of my presentation! Feel free to send your thoughts, whatever they are.
On the other hand, I saw some really interesting presentations, to name a few, from Nuno Antunes, Nuno Godinho, Filipe Prezado, Nuno Silva and my friend André Lage. I also had the chance to finally meet Caio Proiete and Pedro Perfeito.
Perhaps we'll meet again at TechDays Remix, who knows.
Updated as of October 18th
Here's a personal list of some of Microsoft's available and updated developer training kits:
I took the 71-515 exam today. 85 questions, 240 minutes. Here are some notes:
- Great number of jQuery questions, mostly having to do with AJAX
- Lots of MVC 2 questions also
- A number of classic ASP.NET web forms, of which only a few were related with the new 4 features
- Some Entity Framework
- Some plain old JavaScript, like, changing an image dynamically
I think I did OK. As with my previous exam, I still don't know if I passed or not, will have to wait for the end of the beta period.
Continuing my previous posts on dynamic LINQ, now it's time for dynamic filtering. For now, I'll focus on string matching.
There are four standard operators for string matching, which both NHibernate, Entity Framework and LINQ to SQL recognize:
- Equals
- Contains
- StartsWith
- EndsWith
So, if we want to apply filtering by one of these operators on a string property, we can use this code:
public enum MatchType
{
StartsWith = 0,
EndsWith = 1,
Contains = 2,
Equals = 3
}
public static List<T> Filter<T>(IEnumerable<T> enumerable, String propertyName, String filter, MatchType matchType)
{
return (Filter(enumerable, typeof(T), propertyName, filter, matchType) as List<T>);
}
public static IList Filter(IEnumerable enumerable, Type elementType, String propertyName, String filter, MatchType matchType)
{
MethodInfo asQueryableMethod = typeof(Queryable).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(m => (m.Name == "AsQueryable") && (m.ContainsGenericParameters == false)).Single();
IQueryable query = (enumerable is IQueryable) ? (enumerable as IQueryable) : asQueryableMethod.Invoke(null, new Object [] { enumerable }) as IQueryable;
MethodInfo whereMethod = typeof(Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == "Where").ToArray() [ 0 ].MakeGenericMethod(elementType);
MethodInfo matchMethod = typeof(String).GetMethod
(
(matchType == MatchType.StartsWith) ?
"StartsWith" :
(matchType == MatchType.EndsWith) ?
"EndsWith" :
(matchType == MatchType.Contains) ?
"Contains" :
"Equals",
new Type [] { typeof(String) }
);
PropertyInfo displayProperty = elementType.GetProperty(propertyName, BindingFlags.Public | BindingFlags.Instance);
MemberExpression member = Expression.MakeMemberAccess(Expression.Parameter(elementType, "n"), displayProperty);
MethodCallExpression call = Expression.Call(member, matchMethod, Expression.Constant(filter));
LambdaExpression where = Expression.Lambda(call, member.Expression as ParameterExpression);
query = whereMethod.Invoke(null, new Object [] { query, where }) as IQueryable;
MethodInfo toListMethod = typeof(Enumerable).GetMethod("ToList", BindingFlags.Static | BindingFlags.Public).MakeGenericMethod(elementType);
IList list = toListMethod.Invoke(null, new Object [] { query }) as IList;
return (list);
}
var list = new [] { new { A = "aa" }, new { A = "aabb" }, new { A = "ccaa" }, new { A = "ddaadd" } };
var contains = Filter(list, "A", "aa", MatchType.Contains);
var endsWith = Filter(list, "A", "aa", MatchType.EndsWith);
var startsWith = Filter(list, "A", "aa", MatchType.StartsWith);
var equals = Filter(list, "A", "aa", MatchType.Equals);
Perhaps I'll write some more posts on this subject in the near future.
You may recall my post on Dynamic LINQ. I said then that you had to download Microsoft's samples and compile the DynamicQuery project (or just grab my copy), but there's another way. It turns out Microsoft included the Dynamic LINQ classes in the System.Web.Extensions assembly, not the one from ASP.NET 2.0, but the one that was included with ASP.NET 3.5! The only problem is that all types are private:
Here's how to use it:
Assembly asm = typeof(UpdatePanel).Assembly;
Type dynamicExpressionType = asm.GetType("System.Web.Query.Dynamic.DynamicExpression");
MethodInfo parseLambdaMethod = dynamicExpressionType.GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => (m.Name == "ParseLambda") && (m.GetParameters().Length == 2)).Single().MakeGenericMethod(typeof(DateTime), typeof(Boolean));
Func<DateTime, Boolean> filterExpression = (parseLambdaMethod.Invoke(null, new Object [] { "Year == 2010", new Object [ 0 ] }) as Expression<Func<DateTime, Boolean>>).Compile();
List<DateTime> list = new List<DateTime> { new DateTime(2010, 1, 1), new DateTime(1999, 1, 12), new DateTime(1900, 10, 10), new DateTime(1900, 2, 20), new DateTime(2012, 5, 5), new DateTime(2012, 1, 20) };
IEnumerable<DateTime> filteredDates = list.Where(filterExpression);
Since .NET 3.5 brought us LINQ and expressions, I became a great fan of these technologies. There are times, however, when strong typing cannot be used - for example, when you are developing an ObjectDataSource and you need to do paging having just a column name, a page index and a page size, so I set out to fix this. Yes, I know about Dynamic LINQ, and even talked on it previously, but there's no need to add this extra assembly.
So, without further delay, here's the code, in both generic and non-generic versions:
public static IList ApplyPagingAndSorting(IEnumerable enumerable, Type elementType, Int32 pageSize, Int32 pageIndex, params String [] orderByColumns)
{
MethodInfo asQueryableMethod = typeof(Queryable).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(m => (m.Name == "AsQueryable") && (m.ContainsGenericParameters == false)).Single();
IQueryable query = (enumerable is IQueryable) ? (enumerable as IQueryable) : asQueryableMethod.Invoke(null, new Object [] { enumerable }) as IQueryable;
if ((orderByColumns != null) && (orderByColumns.Length > 0))
{
PropertyInfo orderByProperty = elementType.GetProperty(orderByColumns [ 0 ]);
MemberExpression member = Expression.MakeMemberAccess(Expression.Parameter(elementType, "n"), orderByProperty);
LambdaExpression orderBy = Expression.Lambda(member, member.Expression as ParameterExpression);
MethodInfo orderByMethod = typeof(Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == "OrderBy").ToArray() [ 0 ].MakeGenericMethod(elementType, orderByProperty.PropertyType);
query = orderByMethod.Invoke(null, new Object [] { query, orderBy }) as IQueryable;
if (orderByColumns.Length > 1)
{
MethodInfo thenByMethod = typeof(Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static).Where(m => m.Name == "ThenBy").ToArray() [ 0 ].MakeGenericMethod(elementType, orderByProperty.PropertyType);
PropertyInfo thenByProperty = null;
MemberExpression thenByMember = null;
LambdaExpression thenBy = null;
for (Int32 i = 1; i < orderByColumns.Length; ++i)
{
thenByProperty = elementType.GetProperty(orderByColumns [ i ]);
thenByMember = Expression.MakeMemberAccess(Expression.Parameter(elementType, "n"), thenByProperty);
thenBy = Expression.Lambda(member, member.Expression as ParameterExpression);
query = thenByMethod.Invoke(null, new Object [] { query, thenBy }) as IQueryable;
}
}
}
if (pageSize > 0)
{
MethodInfo takeMethod = typeof(Queryable).GetMethod("Take", BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType);
MethodInfo skipMethod = typeof(Queryable).GetMethod("Skip", BindingFlags.Public | BindingFlags.Static).MakeGenericMethod(elementType);
query = skipMethod.Invoke(null, new Object [] { query, pageSize * pageIndex }) as IQueryable;
query = takeMethod.Invoke(null, new Object [] { query, pageSize }) as IQueryable;
}
MethodInfo toListMethod = typeof(Enumerable).GetMethod("ToList", BindingFlags.Static | BindingFlags.Public).MakeGenericMethod(elementType);
IList list = toListMethod.Invoke(null, new Object [] { query }) as IList;
return (list);
}
public static List<T> ApplyPagingAndSorting<T>(IEnumerable<T> enumerable, Int32 pageSize, Int32 pageIndex, params String [] orderByColumns)
{
return (ApplyPagingAndSorting(enumerable, typeof(T), pageSize, pageIndex, orderByColumns) as List<T>);
}
List<DateTime> list = new List<DateTime> { new DateTime(2010, 1, 1), new DateTime(1999, 1, 12), new DateTime(1900, 10, 10), new DateTime(1900, 2, 20), new DateTime(2012, 5, 5), new DateTime(2012, 1, 20) };
List<DateTime> sortedList = ApplyPagingAndSorting(list, 3, 0, "Year", "Month", "Day");
I had the chance to take the beta version of exam 71-516 today. Here are my thoughts on it: first, I was rather annoyed to discover that I will only know if I passed or not about 8 weeks after the beta period expires (July, 02), which probably means September. It was a difficult exam, especially since I don't have any practice on some of the new Entity Framework options. The items covered, from the most covered to the least covered, were:
- Entity Framework (50-50 for POCO/Non-POCO)
- LINQ to SQL
- WCF Data Services
- Classic ADO.NET (DataSets, DataTables, DataAdapters, TableAdapters, Connections and Commands
- LINQ to XML
- Sync Framework (surprise!)
All added up, I think it was a difficult exam. My advise is that you practice a lot! I will post the result as soon as I know it.
Yep, there's still another one: FormatterServices. This one allows one to create an object without running it's constructor... it is used by some of our good friends serializers.
Stopwatch watch = new Stopwatch();
for (Int32 i = 0; i < 100; ++i)
{
StringBuilder builder = FormatterServices.GetUninitializedObject(typeof(StringBuilder)) as StringBuilder;
}
Int64 time4 = watch.ElapsedTicks;
Beware, though: because the constructor isn't run (and remember that all fields that are initialized inline are also in fact initialized in the constructor), the object's state may be invalid.
Enough object construction for now...
More Posts
Next page »