Monday, May 16, 2016

Deserializing XML in .NET

At first glance it seems reasonable that the following XML would be nicely deserialized into the .NET class below.
<?xml version="1.0" encoding="UTF-8"?>
<GetTicketHTTPResponse>
    <ticket>b99a2231-c0a8-0c21-7dd8-76fde0745043</ticket>
    <expires>1463445966897</expires>
    <userid>30269422</userid>
</GetTicketHTTPResponse>
[DataContract(Name = "GetTicketHTTPResponse")]
public class GetTicketHTTPResponse
{
    [DataMember(Name = "ticket")]
    public string Ticket { get; set; }

    [DataMember(Name = "expires")]
    public string Expires { get; set; }

    [DataMember(Name = "userid")]
    public string UserId { get; set; }
}
But NO, it will NOT. The .NET DataContractSerializer assumes that the XML elements appear in alphabetical order and since they do not the expires element will be ignored. The following slightly changed code though will save the day.
[DataContract(Name = "GetTicketHTTPResponse")]
public class GetTicketHTTPResponse
{
    [DataMember(Name = "ticket", Order = 1)]
    public string Ticket { get; set; }

    [DataMember(Name = "expires", Order = 2)]
    public string Expires { get; set; }

    [DataMember(Name = "userid", Order = 3)]
    public string UserId { get; set; }
}

Wednesday, December 2, 2015

Mulitple profiles in AnyConnect drop down list

Add the following to the file AnnyConnectProfile.xml in directory  "%ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client\Profile" to get multiple hosts to choose from in your AnyConnect drop down list.

<?xml version="1.0" encoding="UTF-8"?>
<AnyConnectProfile xmlns="http://schemas.xmlsoap.org/encoding/">;
  <ServerList>
    <HostEntry>
      <HostName>Hostname 1</HostName>
      <HostAddress>Host 1</HostAddress>
    </HostEntry>
    <HostEntry>
      <HostName>Hostname 2</HostName>
      <HostAddress>Host 2</HostAddress>
    </HostEntry>
  </ServerList>
</AnyConnectProfile>

Wednesday, October 1, 2014

Declaring a list variable in SQL

DECLARE @Vowels TABLE (ColumnName CHAR(1))
INSERT INTO @Vowels VALUES ('a')
INSERT INTO @Vowels VALUES ('e')
INSERT INTO @Vowels VALUES ('i')
INSERT INTO @Vowels VALUES ('o')
INSERT INTO @Vowels VALUES ('u')
INSERT INTO @Vowels VALUES ('y')
INSERT INTO @Vowels VALUES ('å')
INSERT INTO @Vowels VALUES ('ä')
INSERT INTO @Vowels VALUES ('ö')


SELECT ColumnName FROM @Vowels

Monday, September 29, 2014

Interesting reads

The purpose of this blog post is to help me remember interesting articles.

Friday, September 19, 2014

Using a DateTimePicker in a BindingNavigators ToolStrip, or any other ToolStrip I assume

There is a dropdown menu in the binding navigator toolstrip (Windows Forms) where you can insert various controls. The DateTimePicker is not one of them though but that can be easily circumvented. All you need to do is to add something like the following in your form constructor/initializer and you have a picker right where you want it.

var picker = new DateTimePicker();
var host = new ToolStripControlHost(picker);
bindingNavigator.Items.Add(host);

Friday, April 11, 2014

Speeding up inserts using Linq-To-Entities - Part 4 (EF 6.1)

This is yet another post about speeding up inserts using the entity framework. Previously I have written about this in the following posts.
  1. Speeding up inserts using Linq-To-Entities - Part 3 (EF 6.0)
  2. Speeding up inserts using Linq-To-Entities - Part 2 (EF 5)
  3. Speeding up inserts using Linq-To-Entities - Part 1
  4. http://blog.tanneryd.com/2011/11/speeding-up-inserts-using-linq-to-sql.html
  5. http://blog.tanneryd.com/2011/12/speeding-up-inserts-using-linq-to-sql.html
This time the code is adapted for EF 6.1. It's pretty much the same as for EF 6.0 but there are some subtle differences.

    public partial class MyEntities
    {
        private Dictionary<string, object> _cache;
        public Dictionary<string, object> Cache
        {
            get { return _cache ?? (_cache = new Dictionary<string, object>()); }
        }

        public MyEntities(string nameOrConnectionString)
            : base(string.Format("name={0}", nameOrConnectionString))
        {            
        }

        public void BulkInsertAll<T>(T[] entities) where T : class
        {
            var conn = (SqlConnection)Database.Connection;

            conn.Open();
            
            Type t = typeof(T);
            Set(t).ToString();
            var objectContext = ((IObjectContextAdapter)this).ObjectContext;
            var workspace = objectContext.MetadataWorkspace;
            var mappings = GetMappings(workspace, objectContext.DefaultContainerName, typeof(T).Name);

            var tableName = GetTableName<T>();
            var bulkCopy = new SqlBulkCopy(conn) { DestinationTableName = tableName };

            // Foreign key relations show up as virtual declared 
            // properties and we want to ignore these.
            var properties = t.GetProperties().Where(p => !p.GetGetMethod().IsVirtual).ToArray();
            var table = new DataTable();
            foreach (var property in properties)
            {
                Type propertyType = property.PropertyType;

                // Nullable properties need special treatment.
                if (propertyType.IsGenericType &&
                    propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                {
                    propertyType = Nullable.GetUnderlyingType(propertyType);
                }

                // Since we cannot trust the CLR type properties to be in the same order as
                // the table columns we use the SqlBulkCopy column mappings.
                table.Columns.Add(new DataColumn(property.Name, propertyType));
                var clrPropertyName = property.Name;
                var tableColumnName = mappings[property.Name];
                bulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping(clrPropertyName, tableColumnName));
            }

            // Add all our entities to our data table
            foreach (var entity in entities)
            {
                var e = entity;
                table.Rows.Add(properties.Select(property => GetPropertyValue(property.GetValue(e, null))).ToArray());
            }

            // send it to the server for bulk execution
            bulkCopy.BulkCopyTimeout = 5*60;
            bulkCopy.WriteToServer(table);

            conn.Close();
        }

        private string GetTableName<T>() where T : class
        {
            var dbSet = Set<T>();
            var sql = dbSet.ToString();
            var regex = new Regex(@"FROM (?<table>.*) AS");
            var match = regex.Match(sql);
            return match.Groups["table"].Value;
        }

        private object GetPropertyValue(object o)
        {
            if (o == null)
                return DBNull.Value;
            return o;
        }

        private Dictionary<string, string> GetMappings(MetadataWorkspace workspace, string containerName, string entityName)
        {
            var mappings = new Dictionary<string, string>();
            var storageMapping = workspace.GetItem<GlobalItem>(containerName, DataSpace.CSSpace);
            dynamic entitySetMaps = storageMapping.GetType().InvokeMember(
                "EntitySetMappings",
                BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance,
                null, storageMapping, null);

            foreach (var entitySetMap in entitySetMaps)
            {
                var typeMappings = GetArrayList("EntityTypeMappings", entitySetMap);
                dynamic typeMapping = typeMappings[0];
                dynamic types = GetArrayList("EntityTypes", typeMapping);

                if (types[0].Name == entityName)
                {
                    var fragments = GetArrayList("Fragments", typeMapping);
                    var fragment = fragments[0];
                    var properties = GetArrayList("PropertyMappings", fragment);
                    foreach (var property in properties)
                    {
                        var edmProperty = GetProperty("Property", property);
                        var columnProperty = GetProperty("Column", property);
                        mappings.Add(edmProperty.Name, columnProperty.Name);
                    }
                }
            }

            return mappings;
        }

        private ArrayList GetArrayList(string property, object instance)
        {
            var type = instance.GetType();
            var objects = (IEnumerable)type.InvokeMember(
                property, 
                BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null, instance, null);
            var list = new ArrayList();
            foreach (var o in objects)
            {
                list.Add(o);
            }
            return list;
        }

        private dynamic GetProperty(string property, object instance)
        {
            var type = instance.GetType();
            return type.InvokeMember(property, BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null, instance, null);
        }


        private bool disposed = false;
        protected override void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    Cache.Clear();
                }
                disposed = true;
            }
            base.Dispose(disposing);
        }
    }

Tuesday, March 11, 2014

Speeding up inserts using Linq-To-Entities - Part 3 (EF 6)

This is yet another post about speeding up inserts using the entity framework. The latest post in this serie can be found at
Speeding up inserts using Linq-To-Entities - Part 4

This time the code is adapted for EF 6. It's pretty much the same as for EF 5 but there are some subtle differences.

public partial class CMLocalEntities
{
    public void BulkInsertAll<T>(T[] entities) where T : class
    {
        var conn = (SqlConnection)Database.Connection;

        conn.Open();

        Type t = typeof(T);
        Set(t).ToString();
        var objectContext = ((IObjectContextAdapter)this).ObjectContext;
        var workspace = objectContext.MetadataWorkspace;
        var mappings = GetMappings(workspace, objectContext.DefaultContainerName, typeof(T).Name);

        var tableName = GetTableName<T>();
        var bulkCopy = new SqlBulkCopy(conn) { DestinationTableName = tableName };

        // Foreign key relations show up as virtual declared 
        // properties and we want to ignore these.
        var properties = t.GetProperties().Where(p => !p.GetGetMethod().IsVirtual).ToArray();
        var table = new DataTable();
        foreach (var property in properties)
        {
            Type propertyType = property.PropertyType;

            // Nullable properties need special treatment.
            if (propertyType.IsGenericType &&
                propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                propertyType = Nullable.GetUnderlyingType(propertyType);
            }

            // Since we cannot trust the CLR type properties to be in the same order as
            // the table columns we use the SqlBulkCopy column mappings.
            table.Columns.Add(new DataColumn(property.Name, propertyType));
            var clrPropertyName = property.Name;
            var tableColumnName = mappings[property.Name];
            bulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping(clrPropertyName, tableColumnName));
        }

        // Add all our entities to our data table
        foreach (var entity in entities)
        {
            var e = entity;
            table.Rows.Add(properties.Select(property => GetPropertyValue(property.GetValue(e, null))).ToArray());
        }

        // send it to the server for bulk execution
        bulkCopy.BulkCopyTimeout = 5*60;
        bulkCopy.WriteToServer(table);

        conn.Close();
    }

    private string GetTableName<T>() where T : class
    {
        var dbSet = Set<T>();
        var sql = dbSet.ToString();
        var regex = new Regex(@"FROM (?<table>.*) AS");
        var match = regex.Match(sql);
        return match.Groups["table"].Value;
    }

    private object GetPropertyValue(object o)
    {
        if (o == null)
            return DBNull.Value;
        return o;
    }

    private Dictionary<string, string> GetMappings(MetadataWorkspace workspace, string containerName, string entityName)
    {
        var mappings = new Dictionary<string, string>();
        var storageMapping = workspace.GetItem<GlobalItem>(containerName, DataSpace.CSSpace);
        dynamic entitySetMaps = storageMapping.GetType().InvokeMember(
            "EntitySetMaps",
            BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance,
            null, storageMapping, null);

        foreach (var entitySetMap in entitySetMaps)
        {
            var typeMappings = GetArrayList("EntityTypeMappings", entitySetMap);
            dynamic typeMapping = typeMappings[0];
            dynamic types = GetArrayList("Types", typeMapping);

            if (types[0].Name == entityName)
            {
                var fragments = GetArrayList("MappingFragments", typeMapping);
                var fragment = fragments[0];
                var properties = GetArrayList("AllProperties", fragment);
                foreach (var property in properties)
                {
                    var edmProperty = GetProperty("EdmProperty", property);
                    var columnProperty = GetProperty("ColumnProperty", property);
                    mappings.Add(edmProperty.Name, columnProperty.Name);
                }
            }
        }

        return mappings;
    }

    private ArrayList GetArrayList(string property, object instance)
    {
        var type = instance.GetType();
        var objects = (IEnumerable)type.InvokeMember(
            property, 
            BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null, instance, null);
        var list = new ArrayList();
        foreach (var o in objects)
        {
            list.Add(o);
        }
        return list;
    }

    private dynamic GetProperty(string property, object instance)
    {
        var type = instance.GetType();
        return type.InvokeMember(property, BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Instance, null, instance, null);
    }

}