Click here to Skip to main content
15,886,806 members
Articles / Programming Languages / SQL

SqlLinq: Taking LINQ to SQL in the Other Direction

Rate me:
Please Sign up or sign in to vote.
4.96/5 (50 votes)
12 Nov 2009CPOL13 min read 103.6K   1.1K   145  
Parsing SQL statements to create LINQ Expressions.
using System;
using System.Linq;
using System.Reflection;
using System.Diagnostics;
using System.Collections.Generic;

namespace Kackman.Framework
{
    public sealed class PropertyLink : IDisposable
    {
        private object m_object1;
        private object m_object2;

        private string m_propertyName;

        public PropertyLink(object object1, object object2, string propertyName)
        {
            Debug.Assert(object1 != null);
            Debug.Assert(object2 != null);
            Debug.Assert(string.IsNullOrEmpty(propertyName) == false);

            m_object1 = object1;
            m_object2 = object2;
            m_propertyName = propertyName;

            SyncValues(m_object1, m_object2, m_propertyName);

            Bind();
        }
 
        public object Object1 { get { return m_object1; } }

        public object Object2 { get { return m_object2; } }

        public string PropertyName { get { return m_propertyName; } }

        public static IEnumerable<PropertyLink> LinkProperties(object object1, object object2, string[] propertyNames)
        {
            Debug.Assert(propertyNames != null);
            List<PropertyLink> list = new List<PropertyLink>();

            foreach (string propertyName in propertyNames)
                list.Add(new PropertyLink(object1, object2, propertyName));

            return list;
        }

        private static void SyncValues(object source, object target, string propertyName)
        {
            PropertyInfo sourceProperty = source.GetType().GetProperty(propertyName);
            Debug.Assert(sourceProperty != null);
            Debug.Assert(sourceProperty.CanRead);
            Debug.Assert(sourceProperty.CanWrite);

            PropertyInfo targetProperty = target.GetType().GetProperty(propertyName);
            Debug.Assert(targetProperty != null);
            Debug.Assert(targetProperty.CanRead);
            Debug.Assert(targetProperty.CanWrite);

            targetProperty.SetValue(target, sourceProperty.GetValue(source, null), null);
        }

        public void Bind()
        {
            Bind(m_object1, new EventHandler(Object1_PropertyChanged));
            Bind(m_object2, new EventHandler(Object2_PropertyChanged));
        }

        public void Unbind()
        {
            Unbind(m_object1, new EventHandler(Object1_PropertyChanged));
            Unbind(m_object2, new EventHandler(Object2_PropertyChanged));
        }

        public void Dispose()
        {
            Unbind();
            GC.SuppressFinalize(this);
        }

        private void Bind(object o, Delegate d)
        {
            EventInfo e = o.GetType().GetEvent(m_propertyName + "Changed");
            Debug.Assert(e != null);
            e.AddEventHandler(o, d);
        }

        private void Unbind(object o, Delegate d)
        {
            EventInfo e = o.GetType().GetEvent(m_propertyName + "Changed");
            Debug.Assert(e != null);
            e.RemoveEventHandler(o, d);
        }

        private void Object1_PropertyChanged(object sender, EventArgs args)
        {
            Unbind(m_object2, new EventHandler(Object2_PropertyChanged));

            SyncValues(m_object1, m_object2, m_propertyName);

            Bind(m_object2, new EventHandler(Object2_PropertyChanged));
        }

        private void Object2_PropertyChanged(object sender, EventArgs args)
        {
            Unbind(m_object1, new EventHandler(Object1_PropertyChanged));

            SyncValues(m_object2, m_object1, m_propertyName);

            Bind(m_object1, new EventHandler(Object1_PropertyChanged));
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Team Leader Starkey Laboratories
United States United States
The first computer program I ever wrote was in BASIC on a TRS-80 Model I and it looked something like:
10 PRINT "Don is cool"
20 GOTO 10

It only went downhill from there.

Hey look, I've got a blog

Comments and Discussions