Repository base classes with LINQ to SQL and performance.

July 18, 2008 19:14 by Rob

I read an article on CodeProject about implementing the repository pattern with Linq To SQL.

I tried that approach because it sounded very nice. I did have some problems with performance and after a few debugging sessions (showing the SQL trace or the DataContext log) I found the problem.


By defining the virtual methods of the repository base class like this: public IEnumerable<T> FindAll(Func<T, bool> exp) the Func will not be (what I call) a delayed method, but it will be expanded immediately. I checked the log from the DataContext and it shows that the table is no longer queries using a where clause. Instead, a full table load is performed and the function is evaluated in memory.


However, the solution is very easy, although this mean you'll have to include the Linq assemblies to your testing bed:

protected T Single(System.Linq.Expressions.Expression<Func<T, bool>> exp)
{
    return Items.Single(exp);
}


The trick is to wrap your functions in a System.Linq expression. Client usage is exactly the same. The performance gain on my project was huge, If you consider that tables are no longer loaded completely into memory.

The full code for my repository base class is in the link below.

Repository.cs (4,64 kb)


Be the first to rate this post

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

Dynamic Data and Silverlight?

July 6, 2008 19:00 by Rob

Yesterday I saw a demo on the new Dynamic Data contribution to Asp.net 3.5. It literally blew me away (really) because that was what I've been doing for most of my time over the last couple of years.

The base

Basically, we develop custom data driven web sites with Asp.net. Most of the time this also involves some kind of back-end content management. What our mini-cms actually did was the following:

  • Inspect the database model
  • Enrich that model with metadata such as preferred input method, validation and comments and associations,
  • Generate a whole lot of Asp.Net controls from the aforementioned properties,
  • Inject a lot of role-based security-stuff,
  • Present those forms to the end-user to allow basic site management.

So, what we had to build was a configuration file with all the meta data, the database, and of course the web site that got driven by that data.

Not any more. I'm out of a job.

With Visual Studio 2008, Asp.Net 3.5 framework and Dynamic Data the generic application that we wrote can be thrown out of the window, because with the DataContext designer this is not longer something somebody else will pay us to do. As you can see in the demo, by binding your decorated data model to the starter solution, you have an interface in a matter of minutes.

Fortunately the Internet-facing site cannot be generated yet. And, we can embrace the DynamicData technology to our advantage and create sites even faster.

On to the subject of this post!

Silverlight and Dynamic Data

Now this is all nice, but there is a simple problem. If I wanted to use this technology with Silverlight, In the last couple of weeks, I was working on a Silverlight application for our content management concept, and I was wondering if the object model could be easily extracted with the new LINQ To SQL designer. I would have to transfer all meta data and content through a WCF service, right?

Lucky for me, the DynamicData layer isn't even finished and does not yet generate WCF services. So, in order to build a generic Silverlight application you would have to serialize a lot of unknown types into a Silverlight application that was unaware of those types. That is not really what I wanted. I wanted a pre-compiled application that can be configured with just a single configuration property: the data model.

I decided to give it a go, and here's what I came up with. I will try to explain it one step at a time.

Here's my very basic data model:

image

Just a news item for a particular category that can have zero or more attachments to it. Nothing fancy.

Using the designer, this stuff generates classes for me with the all the properties and data access methods (select, update, delete etc.) while maintaining all the relations.

Here comes the cool bit: Did you know that the DataContext class actually gives us all the meta data without having to use reflection?  Just drill down into DataContext.Mapping and see that you find there:

image

(edit: since GetTables is a method, it should be written as .GetTables())

Silverlight does not have this nice API, So I created my own WCF contract to serialize these properties in a separate class. Here's a sample of the type specification that I use to transfer to Silverlight (I left the part out that maps the MetaDataMember stuff to my own classes on purpose).

image

To serialize an item of a particular type I perform a generic LINQ select on the table, I read all the properties of a data item and put them in a dictionary so that Silverlight can read and display those items:

image

Notice that for this demo I used the Convert.ToString() method on the value to get a nice presentation of the value. In a future version I will need to put the basic values (int, string, DateTime etc.) in the Values collection.

Of course this is not finished by far. I needed a way to decorate the designed classes with validation, descriptions, etc. Because I do not yet have the DynamicData beta installed on my machine I decided to borrow their approach to decorate generated code. Here's a snippet for the NewsItem class:

image

Because the data context designer generates partial classes, we have the ability to add functionality to those classes. Since I only need to apply some attributes to the generated class I need to define the class again (as partial) and apply my attributes. Since I cannot redefine the properties of that class I have to create an extension class that shadows the properties of the generated class (very nice idea, DynamicData Team!). To use the attributes of the extension class I do need to use reflection, but that is only once. Here's a video of how it works and how it is used. I just copied the concept to there's little more to tell.

A lot of work still needs to be done but I hope you understand that the rest is just more along the same line.

Looks like I still have a job!


Currently rated 5.0 by 2 people

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

Silverlight 2.0 Modified WrapPanel

June 3, 2008 19:18 by Rob

Inspired by this article on Codeproject I decided to give reproduce the wrappanel so I could learn a little more about custom panels in SilverLight 2.0 beta 1. The code provided by Inear has some small problems, one of it not being able to behave properly in a scrollviewer. I made some small adjustments after scourging the internet and here is my solution:

Just before you pass on the ArrangeOverride to the base class, inject this code fragment:

[code:c#] 

if (this.Height != startPoint.Y + largestHeight)

{

this.SetValue(HeightProperty, startPoint.Y + largestHeight);

}

I did make some other small modifications to clean up the code a bit, and I didn't implement the Orientation=Vertical stuff, but check below for the full code.  

WrapPanel.zip (1,11 kb)


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: C# | Silverlight
Actions: E-mail | Permalink | Comments (2) | Comment RSSRSS comment feed

Adding errors to a ValidationSummary

April 24, 2008 14:31 by Rob

Instead of having a custom <asp:Label> with the exception from the backend, you can inject a custom error message to the validationsummary of an asp.net page.

Of course, you could use a server-side validator, but that fires everytime you submit the page, and not only after a succesful post. A Custom Validator is therefore in the wrong place.

Here's what I came up with:

public class CustomValidationError : IValidator

{

private string _message;

public CustomValidationError(string message)

{

_message = message;

}

public string ErrorMessage

{

get { return _message; }set {}

}

public bool IsValid

{

get{ return false; }

set

{

}

}

public void Validate()

{

}

}

To add a custom message to the summary, just do this:

this.Validators.Add(new CustomValidationError("There is no backend!"));


Currently rated 3.5 by 2 people

  • Currently 3.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: ASP.Net | C#
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Three times a column

March 26, 2008 17:09 by Rob

For a client i needed a ASP.Net control that showed its contents in multiple columns. The CSS requirements forced me to develop a custom repeater for it, since the normal ASP.Net controls didn't suit me. I decided to share it with you, so here it is:

This templated databound control will collect items in multiple css div's when rendering. Provide a collection of css classes to indicate the columns (in this example, 3 divs). Rendering will be done from left to right, top to bottom while iterating over the div's.

+------++-------++-------+
| one  || two   || three |
| four || five  ||       |
+------++-------++-------+

[code] public class MultiColumnRepeater : Repeater
    {
        private string _columnClasses;

        /// <summary>
        /// Specifies the amount of columns and their css classes
        /// </summary>
        /// <example>
        /// To create 2 columns, specify "column_left,column_right".
        /// </example>
        public string ColumnClasses
        {
            get { return _columnClasses;  }
            set { _columnClasses = value;  }
        }

        protected override void RenderChildren(HtmlTextWriter writer)
        {
            //iterate over the different items.
            string[] classes = _columnClasses.Split(',');
            for (int column = 0; column < classes.Length; column++)
            {
                writer.AddAttribute(HtmlTextWriterAttribute.Class, classes[column]);
                writer.RenderBeginTag(HtmlTextWriterTag.Div);
               
                //iterate over all children, and only write the ones for the current columns.
                int index = 0;
                foreach (Control control in this.Controls)
                {
                    if (index % classes.Length == column)
                    {
                        control.RenderControl(writer);
                    }
                    index++;
                }

                writer.RenderEndTag();
                writer.Write(writer.NewLine);
            }
        }
    } [/code]


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: ASP.Net | C#
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Why don't you use those expressions regularly?

January 21, 2008 15:45 by Rob
I found a very nice tutorial on Regular Expressions. If you're still a bit uncertain how it al works, or want to brush up on your RegEx skillz, check it out.

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: ASP.Net | C# | Software Engineering
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

EntityPool 2.0 beta

December 4, 2007 14:53 by Rob

Hear! Hear!

The first beta release of EntityPool 2.0.

New features:

  • Support for nullable types
  • Support for orderby filters
  • Compiled against 2.0 framework
  • Added Generic method with lazy-loading interators.
  • Added CreateEntity event for custom entity factories

Here are the downloads.


Currently rated 5.0 by 1 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: C# | EntityPool
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

No More Silverlight 1.1 - I am as amazed as you are.

December 1, 2007 16:19 by Rob

UPDATE: Now that silverlight 2 beta has arrived, I'm feeling a lot better. 

It seems that things are moving faster than I've expected. There has only been an alpha release of Silverlight 1.1, but since it is becoming bigger and bigger the branding people at Microsoft have decided that it is such a huge step forward they've rebranded it to SilverLight 2.0

...We now have a extensible control framework, two-way data binding, templates, styles, all the standard controls (TextBox, ScrollBar, CheckBox, RadioButton etc.), multiple layout containers (Grid, StackPanel, Canvas). In short, if you're familiar with WPF today, you'll be right at home with Silverlight 2.0.

With regards to the Rich Internet Application stuff, here's an interesting quote from the article on Tim Sneath's blog:

Moving forward, if you want to build a rich Internet application, Silverlight should absolutely be at the top of your list for consideration. No other platform will offer such a rich UI framework, and all the data templates and styling capabilities, coupled with the power of the .NET Framework and base class libraries, along with an easy migration path to a full unrestricted Windows desktop solution.

I'd better get up to speed with WPF...


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: C# | Silverlight
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Another pool of entities

November 29, 2007 15:36 by Rob

Dear readers,

 I'm working on a new beta release of EntityPool. The previous releases used only framework 1.1 features and that's practically stoneage. This is the first major update since long time ago. Therefore I decided to call it version 2.0b. Here's a small summary of the changes:

  • 2.0 Generics support including dynamic iterators for dramatic speed increase when working on large collections (see below).
  • Configuration of the connection strings using the new <connectionStrings> settings.
  • Configuration of filters through the web.config/app.config instead of hardcoded attributes.
  • Additional interfaces and events:
    • IConstructedCallBack - an interface that is called after your entity has been constructed from storage
    • IPersistedCallBack - an interface that is called after your entity has been persisted.
    • IRelationBuilder - allows you to define a builder that is used to construct a relation property
    • ConverterAttribute - allows you to declaratively define a converter that is used to map Database values to Entities and vice versa.
  • Strangely enough, there are not that many bugfixes. Maybe the code worked as it should?

As said, you now can specify your query filter in the configuration file instead of using an attribute:

[EntityPool.DefineFilter("byCategory", "Category = @b", "@b")]

You now specify:

<entityPool>


....


 <types>


  <type class="Demo.Objects.Category" assembly="Demo">


   <filters>


    <defineFilter name="byCategory" where="Category = @b" arguments="@b"/>


    <defineFilter name="all" where="1=1 order by Category"/>


  </filters>


 </type>


</types>


</entityPool>

 


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: C# | EntityPool
Actions: E-mail | Permalink | Comments (2) | Comment RSSRSS comment feed

Hola Barcelona!

November 7, 2007 15:07 by Rob

This week I am attending the Microsoft TechEd Developers in Barcelona. Amongst the first impressions where those of dissappointment. First of all it is not that big as the ones I used to attend in Amsterdam. Secondly these seems to be no real new stuff. There is no new product hype. We've all been playing around with the beta's and CTP's of most products for a couple of months now, including Visual Studio 2008, the 3.5 .Net framework and Silverlight 1.1.

What strikes me most are the number of sessions on Silverlight that show basic stuff in 1.0. I attended a couple of sessions on how to communicate with the webserver from 1.0 Silverlight applications using Javascript and AJAX. Why should I want to do that? It will be phased out anyway as soon as 1.1 'hits the shelves'. Even more so, they already have native webservice support built in and working on SL1.1? I do not intend to spend my time working on code that'll be useless in a couple of weeks. Come on TechEd, bring the good stuff !!

This is of course all very reasonable, but the bottom line was reached when a speaker explained how to do c# a ternary operator on a lvl3 advanced course. This would've been fine if it didn't take him 10 minutes.

But the wheather is nice and the evenings are cool, so what am I complaining about?


Be the first to rate this post

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