Source/Tx.SqlServer/XeTypeMap.cs (85 lines of code) (raw):

// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Reactive; using System.Reflection; using Microsoft.SqlServer.XEvent; using Microsoft.SqlServer.XEvent.Linq; namespace Tx.SqlServer { internal class XeTypeMap : IPartitionableTypeMap<PublishedEvent, Guid> { public IEqualityComparer<Guid> Comparer { get { return new GuidComparer(); } } public Guid GetInputKey(PublishedEvent evt) { return evt.UUID; } public Guid GetTypeKey(Type outpuType) { var eventAttribute = outpuType.GetCustomAttribute<XEventAttribute>(); if (eventAttribute == null) return Guid.Empty; return (Guid) eventAttribute.EventGuid; } public Func<PublishedEvent, DateTimeOffset> TimeFunction { get { return evt => evt.Timestamp; } } public Func<PublishedEvent, object> GetTransform(Type outpuType) { ConstructorInfo constrtorInfo = outpuType.GetConstructor(new Type[] {}); if (constrtorInfo == null) throw new Exception("Type " + outpuType.FullName + " does not implement public constructor with no arguments."); ParameterExpression inputEvent = Expression.Parameter(typeof (PublishedEvent), "e"); var bindings = new List<MemberBinding>(); int index = 0; foreach (PropertyInfo property in outpuType.GetProperties()) { Expression readExpression; if (property.GetCustomAttribute<NonPublishedAttribute>() != null) continue; MemberExpression propertyValue = Expression.Property( Expression.Call( Expression.Property(inputEvent, typeof (PublishedEvent).GetProperty("Fields")), typeof (PublishedEvent.FieldList).GetMethod("get_Item", new[] {typeof (int)}), Expression.Constant(index++)), "Value"); if (property.PropertyType.IsSubclassOf(typeof (Enum))) { readExpression = Expression.Convert( Expression.Property( Expression.Convert(propertyValue, typeof (MapValue)), typeof (MapValue).GetProperty("Key")), property.PropertyType); } else { readExpression = Expression.Convert(propertyValue, property.PropertyType); } bindings.Add(Expression.Bind(property, readExpression)); } NewExpression n = Expression.New(constrtorInfo); MemberInitExpression m = Expression.MemberInit(n, bindings.ToArray()); UnaryExpression cast = Expression.Convert(m, typeof (object)); Expression<Func<PublishedEvent, object>> exp = Expression.Lambda<Func<PublishedEvent, object>>(cast, inputEvent); return exp.Compile(); } private class GuidComparer : IEqualityComparer<Guid> { public bool Equals(Guid x, Guid y) { return x.Equals(y); } public int GetHashCode(Guid obj) { return obj.GetHashCode(); } } } }