Archive for category Linq

Tribal Knowledge: Linq Entities To Do Your Bidding via the Partial Keyword in C#

TribalKnowledge2Having premade entities created during the Linq process in .Net really comes in handy. But did you know that one can extend those entities further outside of of the generated dbml file? By using the concept introduced in C# 2.0 of a partial class, where one can have business logic methods and other properties which are not generated but are none the less relevant in an Object Oriented fashion it can be achieved.

As mentioned the entities are generated and nothing is worse than having the generator throw away user code placed in the generated file after a regeneration. To allow for generated and user code to coexist hand in hand was accomplished by partial classes. That is where the partial keyword is appended to a class which allows for the class to have a subset of functionality in a different code file. The generated code file resides in one file and the user code lives elsewhere in a different file allowing them co-exist.

I have used this process to put validation logic on an entity. That logic was used to verify that the differing properties which the user had entered values against matched business rules. Those rules could not be entirely expressed in a database schema. It was very Handy!

Example

A user posted a question on the MSDN Forums as to how one could achieve indexing into a Linq generated class entity where each property represented a numerated indexed field. The below code shows the use of a partial class in a separate file which the user could  have an index-able entity.

public partial class Request
{
    public int this[int index]
    {
        get
        {
            int retValue;

            switch ( index )
            {
                case 0: retValue = Val1; break;
                case 1: retValue = Val2; break;
                case 2: retValue = Val3; break;
            }

            return retValue;
        }
        set
        {
            switch (index)
            {
                case 0: Val1 = value; break;
                case 1: Val2 = value; break;
                case 2: Val3 = value; break;
            }
        }
    }
}
Share

Tags: , , ,

Linq vs. DataReader; Visual Examples Showing That Linq Does it in Fewer Lines of Code

Bridges I recently replied to a post in the MSDN C# General forum (one of the best places to get help if you have C# question) where the user was getting data from a DataReader and needed help with null values being returned. What I ended up discovering was differences from old way of getting data from a database in .Net and the new way. Such as the highways above both go to the same location and essentially do the same thing, but the contrast is so much different. Same holds true for .Net Linq and the DataReader.

In the post I recommend the use of the null-coalescing operator to handle the null returned from the database. Erroneously I forgot that the DataReader returns a DBNull which cannot be handled by the null-coalescing operator. GRRR

My mistake was based in the fact that I have become used to the Linq Data Context returning a INullable<T> when dealing with null fields in a database. The the null-coalescing operator can handle that to a tee.

I created my test code and realized that it demonstrated the following

  1. Linq does so much for the developer that what previously took around six plus lines of code boils down to roughly three. It manages so much in the background for the user that it allows for quicker coding to get at data.
  2. The design of Linq handles Nulls differently, or at lease presents them to the end user from the old way processing. Using the null-coalescing operator as shown is a great help.

Here is the example code, first up is Linq and the target operation is to display values from a nullable field in the database called Description. When enumerating over the data rows, if that field happens to be null it reports it or shows the actual data. Next up is the older way of doing it and notice how the user has to handle reader. Note one could check for DBNull in that situation, so the example may not be what you are looking to do in a real system.

GTCDataContext gtc = new GTCDataContext();

var items = gtc.Location_US;

foreach ( var it in items )
   Console.WriteLine( it.Description ?? "not Defined" );

string queryString = "SELECT Description FROM dbo.Location_US;";

using ( SqlConnection connection = new SqlConnection( gtc.Connection.ConnectionString  ))
{
   SqlCommand command = new SqlCommand( queryString, connection );    connection.Open();

   SqlDataReader reader = command.ExecuteReader();

   // Call Read before accessing data.
   while ( reader.Read() )
   {
      Console.WriteLine( (string.IsNullOrEmpty(reader[0].ToString()) == false) ?  reader[0] : "not defined again" );
   }

    // Call Close when done reading.
    reader.Close();
}

Here is the result of the run:

Florida

not Defined

Colorado

California

not Defined

not Defined

not Defined

not Defined

—————————————–

Florida

not defined again

Colorado

California

not defined again

not defined again

not defined again

not defined again

Share

Tags: , , , , ,

Asp.Net DropDownList bound with Linq Data Example

I recently answered a post where the user was using ASP .Net 3.5 but not binding data to a DropDownList but instead using hard coded data to load the drop down in the HTML. So I created this quick example to show Linq-To-Xml (Linq) loading of an Asp.Net DropDownList and handling the automatic postback selection changes.

As mentioned example shows how to bind data to a dropdown list using Linq, specifically Linq-To-Xml, but you could use any other of the Linq methodologies because we are using the anonymous types to work with the needs of the DropDownList.

First we will place the Asp.Net DropDownListon our page along with a label which will used to show state changes.

<asp:DropDownList ID="ddlMain"
      runat="server"
      AutoPostBack="true"
      OnSelectedIndexChanged="SelectionMade" />

<asp:Label ID="lblWhat" runat="server"/>

Nothing earth shattering here, we have AutoPostBack because we want the control to tell our code behind on the server when a selection has been made. Following that we have the method which will be called for that event of SelectionMade.

The next thing is to load the DropDownList with values to choose from. We will use an XElement loaded dynamically to show how to do do this in Linq. The other thing of note is that we only want load this once, so we check the postback status. If its a postback, we do not reload.

protected void Page_Load( object sender, EventArgs e )
{

if ( Page.IsPostBack == false ) // Only do this once
{
   // Simulate an Linq-To-SQL call with an Linq-To-SQL
   // So anyone can use this demo.
   XElement dataForList
       = new XElement(
           "DropDownData",
             new XElement( "Node",
                 new XElement( "Text", "Selection 1"  ),
                 new XElement( "Data", "1Selection" ) ),
             new XElement( "Node",
                 new XElement( "Text", "Selection 2" ),
                 new XElement( "Data", "2Selection"  ) ));


   var toTheScreen = from x in dataForList.Descendants( "Node" )
                 select new
                 {
                     Text = x.Descendants( "Text" ).First().Value,
                     Value = x.Descendants( "Data" ).First().Value
                 };

    ddlMain.DataTextField = "Text";
    ddlMain.DataValueField = "Value";
    ddlMain.DataSource = toTheScreen;
    ddlMain.DataBind();
}

}

As shown above we work through all the elements named Node. For each of those nodes we will create a new entity with two properties Text and Value. Text will be shown to the user and value is what is associated with the selection. In the binding operations we specify the Text and Value field for the DropDownList to use and simply bind it to our anonymous projection.

Now all we have to do is handle the selection change event

protected void SelectionMade( object sender, EventArgs e )
{
    DropDownList target = sender as DropDownList;

    if ( target != null )
        lblWhat.Text =
            string.Format(
                "Item {0} selected with Value of {1}",
                target.SelectedItem.Text,
                target.SelectedValue );
}

Nothing magical here, we get the DropDownList from the sender argument, divine the selection and update the label. Here is what it should look like after a change:

ddl

Share

Tags: , , ,

C# XML Parsing Extracting Values and using XML to Linq with XDocument

On my blog the most accessed articles are the basic ones on XML which has suprised me. So In this article I will focus on the new kid on the block the Linq derived XDocument. In the following example I will load the Xml then enumerate over the child nodes, to extract specific values and then display them.

I am loading the xml directly, but you can load it from other locations using the Load option of XDocument.

string xml = @"<?xml version='1.0' encoding='UTF-8'?>
<widgets>
    <widget>
        <url>~/Portal/Widgets/ServicesList.ascx</url>
        <castAs>ServicesWidget</castAs>
        <urlType>ascx</urlType>
        <parameters>
            <PortalCategoryId>3</PortalCategoryId>
        </parameters>
    </widget>
    <widget>
        <url>www.omegacoder.com</url>
        <castAs>ServicesWidget</castAs>
        <urlType>htm</urlType>
        <parameters>
            <PortalCategoryId>41</PortalCategoryId>
        </parameters>
    </widget>
</widgets>";

XDocument loaded = XDocument.Parse( xml );

var widgets = from x in loaded.Descendants( "widget" )
              select new
              {
                  URL = x.Descendants( "url" ).First().Value,
                  Category = x.Descendants( "PortalCategoryId" ).First().Value
              };

foreach ( var wd in widgets )
    Console.WriteLine( "Widget at ({0}) has a category of {1}", wd.URL, wd.Category );

/* Outputs:

Widget at (~/Portal/Widgets/ServicesList.ascx) has a category of 3
Widget at (www.omegacoder.com) has a category of 41

*/
Share

Tags: , ,

XPath meets Linq To XML in C#

There are two technologies which I feel that every coder should learn regardless of the language one programs in…those are Regular Expressions and XPath.

XPath is a quirkier language than Regular Expressions, but it is the the linqua-franca for working with xml documents. By specifying an XPath query which mirrors the target nodes one can get nodes from an xml document to be processed in the code.

The forum poster had xml data with a missing node, he had a car example. He wanted all the parent car nodes which had three tires (child nodes) and did not have four. Three wheel cars verse four wheel cars.

The following C# shows how to manipulate the Xpath and retrieve the nodes needed. Note one uses an xml editor with Xpath editing to figure out the stranger derivations.

using System.Xml.Linq;
using System.Xml.XPath;

...

string xml= @"<?xml version='1.0' encoding='UTF-8'?>
<Main>
<cars>
    <car name='Twingo'>
        <wheel1>abc</wheel1>
        <wheel2>def</wheel2>
        <wheel3>ghi</wheel3>
    </car>
    <car name='quattro'>
        <wheel1>some info</wheel1>
        <wheel2>more info</wheel2>
        <wheel3>blur</wheel3>
        <wheel4>We have four tires</wheel4>
    </car>
    <car name='Triumph'>
        <wheel1>some info</wheel1>
        <wheel2>more info</wheel2>
        <wheel3>blur</wheel3>
    </car>
</cars>
</Main>";

XDocument loaded = XDocument.Parse( xml );

IEnumerable<XElement> list1
   = loaded.XPathSelectElements( "//cars/car[not(wheel4)]" );

foreach ( XElement el in list1 )
    Console.WriteLine( el );

/* Outputs
<car name="Twingo">
  <wheel1>abc</wheel1>
  <wheel2>def</wheel2>
  <wheel3>ghi</wheel3>
</car>
<car name="Triumph">
  <wheel1>some info</wheel1>
  <wheel2>more info</wheel2>
  <wheel3>blur</wheel3>
</car>*/
Share

Tags: , , ,

Linq Orderby a Better IComparer in C#

Sometimes IComparer falls short when on has a need to sort on different, for lack of a better term, data columns. Before writing an IComparer interface for sort, try using Linq’s Orderby.

In the forums the user had data, in string lines, which looked like this

3 months ending 9/30/2007
9 months ending 9/30/2007
3 months ending 9/30/2008
9 months ending 9/30/2008

The user needed the white items sorted first in ascending fashion and the red year items sorted descending. Because the data was all in a string and needed differing sorts, je was having problems with sort with a custom IComparer class.

I recommend that he use regex to parse out the items then use linq to sort. Here is the result.  Note I merged all data into one string where each line is a true line.

string input =
@"3 months ending 9/30/2007
9 months ending 9/30/2007
3 months ending 9/30/2008
9 months ending 9/30/2008";

string pattern = @"(?<Total>\d\d?)(?:[^\d]+)(?<Date>[\d/]+)";

var items =
    from Match m in Regex.Matches( input, pattern )
    select new
    {
        Total = m.Groups["Total"].Value,
        Date = DateTime.Parse( m.Groups["Date"].Value ),
        Full = m.Groups[0].Value
    };

var values = from p in items
             orderby p.Total, p.Date.Year descending
             select p;

foreach ( var itm in values )
    Console.WriteLine( itm.Full );

/* Outputs
3 months ending 9/30/2008
3 months ending 9/30/2007
9 months ending 9/30/2008
9 months ending 9/30/2007
             */
Share

Tags: , , , ,

Regex To Linq to Dictionary in C#

This article demonstrates these concepts:

  1. Regex extraction of Key Value pairs and placing them into named capture groups.
  2. Linq extraction of the Key Value pairs extracted from the matches of Regex.
  3. Dictionary creation from Linq using the ToDictionary method.

I answered this on the MSDN forums, the user had this data in key value pairs delimited by the pipe:

abc:1|bbbb:2|xyz:45|p:120

Keys values separators

The need was to get the keys and values into a dictionary. The following code uses named regex group matches which are used in Linq to extract the keys and their values. Once that is done within the linq the extended method ToDictionary is used to create the dictionary on the fly. Here is the code:

string input = "abc:1|bbbb:2|xyz:45|p:120";
string pattern = @"(?<Key>[^:]+)(?:\:)(?<Value>[^|]+)(?:\|?)";

Dictionary<string, string> KVPs
    = ( from Match m in Regex.Matches( input, pattern )
      select new
      {
          key = m.Groups["Key"].Value,
          value = m.Groups["Value"].Value
       }
       ).ToDictionary( p => p.key, p => p.value );

foreach ( KeyValuePair<string, string> kvp in KVPs )
    Console.WriteLine( "{0,6} : {1,3}", kvp.Key, kvp.Value );

/* Outputs:
 abc :   1
bbbb :   2
 xyz :  45
  p  : 120
 */
Share

Tags: , , ,

Active Directory: Get All Users using C# with Linq To Active Directory

I began working on a website which had the requirement of getting all users from Active Directory/LDAP.  I began working on a solution by searching the web. When I ran across a tool LINQ to Active Directory which allows one to use Linq against Active Directory. I found that code to be quite helpful in my task. This article discusses how to use the tool and additional code changes I created to make the tool even more specialized and less prone to memory leaks.

Steps: Get all users.

  1. Download the latest Linq to AD from codeplex LINQ to Active Directory. It expands a demo project and the main library project BdsSoft.DirectoryServices.Linq.
  2. Create a new blank solution and add the BdsSoft.DiretoryServices.Linq  project into it.
  3. Create a new project to consume the library.
  4. In the new project add these references
    1: to the BdsSoft.DirectoryServices
    2: System.DirectoryServices
    3: The com object Active DS Type library:

    Active DS Type Library in the COM tab

  5. Now we have to create our own entity. Basically it is a class where the properties are simply the name of the target LDAP categories. Here are the usings which will be needed:
    using ActiveDs;
    using BdsSoft.DirectoryServices.Linq;
    using System.Linq.Expressions;
    using System.DirectoryServices;
  6. Here is the entity class user which will hold each item:
    [DirectorySchema( "user", typeof( IADsUser ) )]
    class User
    {
        public string Name { get; set; }
    
        public string sAMAccountName { get; set; }
    
        public string objectCategory { get; set; }
    
        public string mail { get; set; }
    
        public string Description { get; set; }
    
        [DirectoryAttribute( "PasswordLastChanged", DirectoryAttributeType.ActiveDs )]
        public DateTime PasswordLastSet { get; set; }
    
        [DirectoryAttribute("distinguishedName")]
        public string Dn { get; set; }
    
        [DirectoryAttribute("memberOf")]
        public string[] Groups { get; set; }
    
    }
  7. The above class uses attributes to inform the Linq To AD library how to handle the entity and if need be change names of each of the properties of the class.
  8. Use this code to access AD from a console app, placing your AD server in the below code:
    static void Main( string[] args )
    {
    
        IEnumerable<User> users = GetADUsers();
    
        Console.WriteLine( "Users: " + users.Count().ToString() );
    
    }
    
    static DirectoryEntry ROOT = new DirectoryEntry( "LDAP://MyADDomainLocation.com" );
    
    private static IEnumerable<User> GetADUsers()
    {
        IEnumerable<User> users;
    
        var usersDS = new DirectorySource<User>( ROOT, SearchScope.Subtree );
    
                users = from usr in usersDS
                        where usr.Name == "A*" // FIlter A then any character(s)
                        select usr;
    
         users = users.OrderBy( user => user.Name ).ToList(); // Sort them alphabetically by name.
    
        return users;
    }

That will get you up and running but there are three problems with the library which you may run into.

  1. The code uses DirectorySearcher..::.FindAll Methodwhich states in the remarks that improper usage may result in a memory leak.
  2. The action even though user is stated, at least in my domain returned non users. A different LDAP category needs to be used.
  3. Doesn’t handle specific LDAP command to ignore inactive users.

I rectify those issues and will detail it in a future post.

Share