My Potential My Passion

You are never given a wish, without also being given the power to make it come true - Richard Bach

Virtual Tech Days AUG 2009

clock August 23, 2009 18:54 by author Sarang

Hello! The VTD this time was exciting and it was fun to do a session on .NET 4.0. I hope most of you benefitted from my session, if not all. Once again, the objective was to put forth some of the interesting issues and problems that we face today in general. Perhaps because the problem initially was not realized or probably because of the framework limitations earlier. Frameworks are ever evolving and as our demands grow in terms of productivity, hardware and software, there is a necessity to constantly upgrade our framework so that it meets the most current and immediate future needs.

.NET Framework 4.0 has a load of new things that specifically target, productivity of the developer, performance of the app and overall scalability of the app to co-align with new hardware paradigm that are lately coming into being.

I wish I had a little bit more time to do a few more demos. Nevertheless, we spoke / touched-base on the following with some demos as well:

  • Code Contracts
  • Background GC
  • Type Equivalence and Type Embedding
  • Dynamic Language Runtime
  • Managed Extensibility Framework

As promised here are some of the demos that I did along with the slide deck. I am intentionally omitting some of the demos, since the code is yet not shareable. However, once I am all set to share that code, I will do so.

Note: The code is for demo purpose only and bucketed from various online / internal sources. I am thankful to my friends in the CLR team for giving me their valuable time and sharing some demos with me in order to make this session successful.

NET4Demos.zip (416.26 kb)

AdvancesInNet4.pdf (543.17 kb)

 

Cheers!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Data Reference Binding for Non-WPF stuff

clock November 16, 2008 04:04 by author Sarang

Well I am sure this is sounding weird when the whole world is all over WPF. However, I am going to mention my experience about some cool stuff that exists in the framework which I have been exploring for the past few days.

I had a funny problem to solve (I am sure there will be lots of folks there who might find this a not so interesting post). We all know that WPF has a great deal of support for data reference binding (DRB) and sure it is. However, in my specific problem, I wanted to utilize the cool feature of WPF DRB without really meaning to write a WPF application. So, let's say I am wanting to replace the data binding capability under System.Data with the one under System.Windows.Data. Why??? because of the cool stuff that it has in it!! And when I say cool stuff I am specifically referring to literal expressions that can be provided in the Path property, ValueConverters that can be used to translate/transform value of one object to another, etc.

WPF DRB largely operates over DependencyObject - type of objects and DependencyProperties - add to it a spicy of INotifyPropertyChanged interface. [Do a search on those three key words and there's plenty of material out there that describes the whats and hows of each of those].

Now I am going to describe two scenarios and how to solve them using DRB. Note, there could be parallel frameworks and technologies that may be able to achieve the same thing. The beauty is how much code you would end up writing. And with WPF DRB, you will be amazed.

Scenario 1:

I want to bind a collection of an entity (e.g. Persons) to a generic object like a Table, which is my middle tier object. This middle tier, generic table will be consumed by the presentation layer (could be winforms, webforms, office apps, anthing) to be rendered as a UI table. Moreover, the declarative side of my app would read a value from the DB like:

"<Table Source=PersonsCollection>"

So essentially what we are doing is

1. Taking an object in one format and converting it into another.

2. Whilst it's converted to another format, we are establishing two-way binding between those two objects. If I change a value in either one of these objects, it will automatically change the corresponding value on the other object. So e.g. if, Table.Rows[0].Cells[0].CellValue represents the PersonName. If I change the CellValue in this scenario, it will automatically change the value on Persons[0].PersonName to which this cell is bound to.

My Table class may look like this:

[Serializable]

public class Table : DependencyObject, INotifyPropertyChanged

{ 

          private Rows _rows = new Rows(); 

          public Rows Rows

          {

             get { return _rows; }

             set { _rows = value; }

          } 

}

[Serializable]

public class Rows : ObservableCollection<Row>

{} 

[Serializable]

public class Row : DependencyObject, INotifyPropertyChanged

{

            private Cells _cells = new Cells(); 

            public Cells Cells

            {

                get { return _cells; }

                set { _cells = value; }

            }

}

[Serializable]

public class Cells : ObservableCollection<Cell>

{}

[Serializable]

public class Cell : DependencyObject, INotifyPropertyChanged

{

          public string CellValue

          {

                get { return (string)this.GetValue(CellValueProperty); }

                set

                {

                    this.SetValue(CellValueProperty, value);

                    OnPropertyChanged("CellValue");

                }

          }

            public static readonly DependencyProperty CellValueProperty = DependencyProperty.Register(

              "CellValue", typeof(string), typeof(Cell), new PropertyMetadata(""));

}

And let's say my Person class and Persons collection class looks like this:

 

[Serializable]

public class Persons: ObservableCollection<IData>

{

}

[Serializable]    

public class Person : IData, INotifyPropertyChanged

{

            private string _pName;

            public string PersonName

            {

                get { return (string)this.GetValue(PersonNameProperty); }

                set

                {

                    this.SetValue(PersonNameProperty, value);

                    OnPropertyChanged("PersonName");

                }

            }

            public static readonly DependencyProperty PersonNameProperty = DependencyProperty.Register(

              "PersonName", typeof(string), typeof(Person), new PropertyMetadata(new Person()));

}

[Serializable]
public abstract class IData : DependencyObject
{}

Before we move ahead here are a quick few things:

1. I am declaring a DependencyObject class - IData (I know it is not an interface). The person class derives from it. And Persons collection is not really a collection of Person object but a collection of IData. Why?? Because I like it that way.

2. Persons collection is of type ObservableCollection - this is a collection class available in the framework and it implements INotifyPropertyChanged.

3. I am declaring DependencyProperties at various places to store values that I am going to use for Binding.

Now, assume that I am given an expression as above with some more information as follows:

"<Table Source=Persons>

<Row Source= ".[i]">         //This maps to Persons[i] --> i.e. Person object at position represented by "i"

      <Cell = ".Persons[i].PersonName"/>   //This is the Property inside the Persons[i]

</Row>

</Table>"

This is more like a template which defines what data my final table should contain.

So in short we are going to take this template and apply it to the Persons collection and get the Table object out of it.

I am not going to paste the whole code here, however, this is what we will do in short:

Table t = new Table();





for (int dataElementCount = 0; dataElementCount < PersonCollection.Count; dataElementCount++)

 {

Row r = new Row();

for (int cellCount = 0; cellCount < NoOfCellsRequiredInTheRow; cellCount++)

{

               Cell c1 = new Cell();

               System.Windows.Data.Binding cellbinding = new System.Windows.Data.Binding();

               cellbinding.Source = dc;

               dataRefExpression = template.Rows[rowTemplateCount].Cells[cellCount].DataReferenceExpression.Replace("[i]", "[" + dataElementCount.ToString() + "]"); --> This will be .Persons[0].PersonName for the element "0".

               cellbinding.Path = new System.Windows.PropertyPath(dataRefExpression);

               cellbinding.Mode = BindingMode.TwoWay;

              //// IMPORTANT NOTE 1: We at this instance know the target DependencyObject (Cell) and the DependencyProperty 

             //// (CellValueProperty) on that object.

               BindingOperations.SetBinding(c1, Cell.CellValueProperty, cellbinding);



               r.Cells.Add(c1);

          }

          

         t.Rows.Add(r);

}

That's it and by the end of it you will have your Generic table ready with TwoWay DRB. So change the CellValue representing the PersonName in the generic table and it will automatically change the underlying Persons collection and vice-versa.

 

Scenario 2:

The second scenario is something like this. A database value has a expression stored like this

"Global.Customers[i].CustomerName" = "Global.Persons[i].PersonName"

This may look simple however, it's really not that simple. Refer to my IMPORTANT NOTE 1 above. The binding to be set successfully requires the target DependencyObject and the DependencyProperty on that object. In this scenario, all I know is the source collection is Persons and Target collection is Customers. However, the expression says "Global.". The reason is to show that the DependencyObject actually lies one level below in the hierarchy this time, so I cannot assume by default that the object corresponding to the "substring" before the first "." (dot) --> Global, is a DependencyObject. So how do we get to the DependencyObject --> Customers[i] and Persons[i]??

Two options that I can immediately think of:

1. Use some smart reflection and take each substring check if it's a DependencyObject then enlist it's dependency properties and see if it is equivalent to the one that we are interested in setting... phew... thinking of it, itself is scary.

2. Put WPF DRB to use.

Wow...did I just reduce the above sentence (1) to 1/10 of it's size?? Well the solution that we will see will have an equivalent effect.

Here's how I tricked WPF DRB to do what I wanted.

I created a dummy class such as:

public class ValueSetter : DependencyProperty , INotifyPropertyChanged

{

        public object Dummy
        {
            get { return (string)this.GetValue(DummyProperty); }
            set
            {
                this.SetValue(DummyProperty, value);
                OnPropertyChanged("Dummy");
            }
        }
        public static readonly DependencyProperty DummyProperty = DependencyProperty.Register(
          "Dummy", typeof(object), typeof(ValueSetter), new PropertyMetadata(new object()));



        public void SetValue(ref ValueSetter vsw2)
        {
            this.Dummy = vsw2.Dummy;
        }

}

And then smarties out there would have guessed what's coming next.

I write the same exact DRB code that I used for Table object above for both my Left side and Right side of the above expression --> "Global.Customers[i].CustomerName" = "Global.Persons[i].PersonName"

ValueSetter vsw1 = new ValueSetter();
ValueSetter vsw2 = new ValueSetter();

Binding bx1 = new System.Windows.Data.Binding();

bx1.Path = new System.Windows.PropertyPath(literalExpression1);
bx1.Source = Source1; /////THIS IS YOUR GLOBALS OBJECT
bx1.Mode = BindingMode.TwoWay;
BindingOperations.SetBinding(vsw1, ValueSetter.DummyProperty, bx1);



Binding bx2 = new System.Windows.Data.Binding();

bx2.Path = new System.Windows.PropertyPath(literalExpression2);
bx2.Source = Source2; ////THIS IS ALSO YOUR GLOBALS OBJECT
bx2.Mode = BindingMode.TwoWay;

BindingOperations.SetBinding(vsw2, ValueSetter.DummyProperty, bx2);

vsw1.SetValue(ref vsw2);

bx1 = null;
bx2 = null;
vsw1 = null;
vsw2 = null;

And Bingo!!!! We have achieved what we wanted to.. the Global.Customers[i].CustomerName will now contain the value represented by Global.Persons[i].PersonName!!!

And the reason why this worked is because of the magic of two way binding. Setting a value from VSW2 on VSW1, caused the binding on VSW1 to automatically change (update) the value on Customers[i].CustomerName which would in this case be bound to VSW1.DummyProperty.

That does it. I hope this code would be found useful. And uh oh... where is XAML and all that WPF thingi.... surprise.. we are not at all touching it here... we are only using the DRB framework...that goes to prove how cool the WPF DRB framework is. Moreover, at this instance we are assigning a primitive value (string) to another string. You can extend this example by actually writing ValueConverter classes and assigning an instance of those to Binding.Converter property.

Lastly... Not even a single line of Reflection!!!  

That's all for now... Cheers!!!

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


Inner Joins in LINQ - deep dive.

clock August 14, 2008 18:09 by author Sarang

I was generally trying to get around a query which had multiple inner joins and also had a blend of 'EXISTS' clause or "IN" clause via LINQ. I searched for sometime over the web and couldn't find nothing, but simple Linq queries... nothing that I could take and reuse really. Here's the query that I was trying to convert to Linq:

SELECT [t1].[ASListID], [t1].[QID]
FROM [Question] AS [t0]
INNER JOIN [QuestionSelection] AS [t1] ON [t0].[QID] = [t1].[QID]
WHERE EXISTS(
SELECT t3.ASListID FROM [AnswerStep] AS [t2]
INNER JOIN [AnswerStepSelection] AS [t3] ON [t2].[ASID] = [t3].[ASID]
INNER JOIN [AnswerStepList] AS [t4] ON [t3].[ASListID] = [t4].[ASListID]
WHERE ([t3].[ASListID] = [t1].[ASListID]) AND ([t4].[QuestionAreaID] = 1)
) 

Now, it may not be the most complicated query in the world (I know), but it can be tricky to convert the whole expression to LINQ.

The best way to approach the problem is to break down the query into two parts
1. Everything uptill "Where Exists"
2. Everything after "Where Exists"

After doing that it might make sense to build the query expression in LINQ for the 2nd part first then check the results, match it with the actual SQL query. If it works fine then proceed to solving the second part.

Likewise to cut the big story short here's what the LINQ query should look like

Part 1:

from p in context.GetTable<ConsoleApplication3.AnswerStep>()
join p1 in context.GetTable<ConsoleApplication3.AnswerStepSelection>()
on p.ASID equals p1.ASID
join p2 in context.GetTable<ConsoleApplication3.AnswerStepList>()
on p1.ASListID equals p2.ASListID
where ((p2.QuestionArea == 1))
select p1.ASListID 

Part 2:

from t in context.GetTable<ConsoleApplication3.MyQuestion>()
join t1 in context.GetTable<ConsoleApplication3.MyQuestionSelection>()
on t.QID equals t1.QID 
select new { t1.ASListID, t1.QID } 

Now that we have both these queries in place we can simply combine them using a "WHERE" and "CONTAINS" clause/methods like this:

from t in context.GetTable<ConsoleApplication3.MyQuestion>()
join t1 in context.GetTable<ConsoleApplication3.MyQuestionSelection>()
on t.QID equals t1.QID
select new { t1.ASListID, t1.QID }).Where(n => (from p in context.GetTable<ConsoleApplication3.AnswerStep>()
join p1 in context.GetTable<ConsoleApplication3.AnswerStepSelection>()
on p.ASID equals p1.ASID
join p2 in context.GetTable<ConsoleApplication3.AnswerStepList>()
on p1.ASListID equals p2.ASListID
where ((p2.QuestionArea == 1))
select p1.ASListID).Contains (n.ASListID) 

 

I hope that helps...feel free to send in your comments. Thanks.

Currently rated 4.0 by 2 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5


About the author

Hi! My name is Sarang and I am glad you dropped in a visit to my blogsite. I am a tech-savy professional and more often that not, you will find blogs related to latest technology and gadgets. However, you will also find that I have a strong inclination towards Microsoft and Microsoft technology....because we build the best software in the world.

DISCLAIMER:

The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of my employer. It is solely my opinion. Inappropriate comments will be deleted at the authors discretion. All code samples are provided "AS IS" without warranty of any kind, either express or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.

Sign in