Archives

Archives / 2008
  • Lazy Loaded One-To-One With NHibernate

    UPDATE 20081114

    The one-to-one solution I had posted turned out not to work for updates, :(, in the end I had to use a many-to-one map with a unique foreign key association to get this to work, the updated example is below. Sorry for my EPIC FAIL :)...

  • Avoid Memory Leaks When Using Windsor And Not Releasing Objects

    I just had this issue in a project I am working on (ASP.NET Webforms Application), yesterday I ran a load test and watched my memory climb rapidly and max out not long after. I am using Castle Windsor for my IOC and mostly transient instances are registered so I did not expect any issues here as I asssumed there would be no references held to my transient instances but the leak shows this is happening.

    I am not releasing my services once done so this is partly my fault but I do not wan't to explicitly release them so I found another way which means setting the ReleasePolicy on the kernel to use the NoTrackingReleasePolicy. The default release policy is the AllComponentsReleasePolicy which from what I can see by debugging will keep track of your instances and you will need to release them manually when you are finished with the item.

  • Extension Method Competition

    I plan on holding an extension method competition, basically the idea is that you submit your favourite most useful/elegant/sexy extension method and these will be judged by a selection of judges (to be picked) and there will also be some form of reward for the winner.

  • Set the value of a version column in NHibernate manually

    My first post in a long time :), look forward to more from me.

    I am currently working on a project and for the first time am using NHibernate, I must say compared to LINQ to Sql I am in love, NHibernate ROCKS! An issue I was having was that I have a version column in my database defined as an integer and then in my NHibernate mapping files have defined a <version> element to map to this column. Now one issue is that in my service methods I do something like this:

    public void Update(MyDTO dto) {

    // Select the item.
    var item = this.repository.SelectById(dto.Id);

    // Map values from DTO to model.
    item.Name = dto.Name;
    item.Version = dto.Version;

    // Call update
    this.repository.Update(item);

    }

    Because I am passing in a DTO object from my UI layer I need to first load the entity from the repository by Id. Then I map across my properties including the version, which in this case was populated from a hidden field on the UI into the DTO. Next I call update, now my initial assumption was that this would work as I excepted for optimistic locking. I thought that for example say the current version in the DB was 2, and the item we are updating is version 1, so it would load the item with a version = 2.

    Then we override the version to 1 and upon update I would expect it to use this version 1 for the optimistic check. WRONG it from what I understand uses the version value which is cached from a copy of the item upon loading it. If you look at the documentation there are 3 types approaches to optimistic concurrency.



    10.4.1. Long session with automatic versioning

    A single ISession instance and its persistent instances are used for the whole application transaction.

    The ISession uses optimistic locking with versioning to ensure that many database transactions appear to the application as a single logical application transaction. The ISession is disconnected from any underlying ADO.NET connection when waiting for user interaction. This approach is the most efficient in terms of database access. The application need not concern itself with version checking or with reattaching detached instances.

    // foo is an instance loaded earlier by the Session
    session.Reconnect();
    transaction = session.BeginTransaction();
    foo.Property = "bar";
    session.Flush();
    transaction.Commit();
    session.Disconnect();
    The foo object still knows which ISession it was loaded it. As soon as the ISession has an ADO.NET connection, we commit the changes to the object.

    This pattern is problematic if our ISession is too big to be stored during user think time, e.g. an HttpSession should be kept as small as possible. As the ISession is also the (mandatory) first-level cache and contains all loaded objects, we can propably use this strategy only for a few request/response cycles. This is indeed recommended, as the ISession will soon also have stale data.

    10.4.2. Many sessions with automatic versioning

    Each interaction with the persistent store occurs in a new ISession. However, the same persistent instances are reused for each interaction with the database. The application manipulates the state of detached instances originally loaded in another ISession and then "reassociates" them using ISession.Update() or ISession.SaveOrUpdate().

    // foo is an instance loaded by a previous Session
    foo.Property = "bar";
    session = factory.OpenSession();
    transaction = session.BeginTransaction();
    session.SaveOrUpdate(foo);
    session.Flush();
    transaction.Commit();
    session.Close();
    You may also call Lock() instead of Update() and use LockMode.Read (performing a version check, bypassing all caches) if you are sure that the object has not been modified.

    10.4.3. Application version checking

    Each interaction with the database occurs in a new ISession that reloads all persistent instances from the database before manipulating them. This approach forces the application to carry out its own version checking to ensure application transaction isolation. (Of course, NHibernate will still update version numbers for you.) This approach is the least efficient in terms of database access.

    // foo is an instance loaded by a previous Session
    session = factory.OpenSession();
    transaction = session.BeginTransaction();
    int oldVersion = foo.Version;
    session.Load( foo, foo.Key );
    if ( oldVersion != foo.Version ) throw new StaleObjectStateException();
    foo.Property = "bar";
    session.Flush();
    transaction.Commit();
    session.close();
    Of course, if you are operating in a low-data-concurrency environment and don't require version checking, you may use this approach and just skip the version check.

    -------------------

    Now if you look at the above it is clear that I am using the third scenario hence why I as having the issues, if I kept the session around for the life of the transaction i.e store in cache when you display the page and then use this session again for the save, the version would have been handled automagically same being if you had the full object and call an Update with it on a new Session.

    But in my case I do not have the full object and am only mapping over a sub set of parameters from my DTO, so I need to first load the item by ID from the session and then map across my parameters, finally calling an update, this is where the issue is. To fix this the solution which I found on the Java forums and adopted was to create an interceptor which would handle the OnFlushDirty method. In here I will compare the Version of the entity being flushed to the Version of the item in the database, this will do what I would like and allows me to set the Version manually.

    The main issue is that there is 1 extra DB call to get the version, but in my case this is minimal. The code for the interceptor is below, it doesn't seem to have any issues as yet but will undergo more testing as time goes by. The solution/ideas came from here: http://forum.hibernate.org/viewtopic.php?t=977889, and was changed to work.


    public class NHInterceptor : EmptyInterceptor {
    private ISession _session;

    public override void SetSession(ISession session) {
    this._session = session;

    base.SetSession(session);
    }

    public override bool OnFlushDirty(object entity, object id, object[] currentState, object[] previousState, string[] propertyNames, NHibernate.Type.IType[] types) {
    ISessionImplementor sessimpl = _session.GetSessionImplementation();
    IEntityPersister persister = sessimpl.GetEntityPersister(entity);
    EntityMode mode = _session.GetSessionImplementation().EntityMode;

    if(persister.IsVersioned) {
    object version = persister.GetVersion(entity, mode);
    object currentVersion = persister.GetCurrentVersion(id, sessimpl);

    if (!persister.VersionType.IsEqual(currentVersion, version))
    throw new StaleObjectStateException(persister.EntityName, id);
    }

    return base.OnFlushDirty(entity, id, currentState, previousState, propertyNames, types);
    }

    }



    Maybe you find this useful.


    Thanks
    Stefan

  • Urchin ELF2 Ecommecre Log File Helper

    Hello,

    I am currently needing to implement ecommerce tracking with our Urchin stats server. To do this it reads your transaction logs that you write to when users buy from your site. This file needs to be in a special format ELF2 click here for more info.

    I though I would write some helper classes to make writing my ELF2 logs easier and something that would be reusable and could even have functionality added in the future to parse the logs (most likely never needed but you never know). So I created a set of classes to do this for me. I will not post the source code right now but if there is interest will tidy it up and release it for all too use.

  • Simplified ASP.NET AJAX Custom Control Development With VS Item Template

    Hello,

    At work today I had a friend (Blair) have issues with trying to get a browser alert to popup on the page during an ASYNC post back. I told him I would make a custom control in 30 secounds or less that would do this and make life much easier. Overkill I know for such a simple task but it was more of a demo to show the ease/speed of creating a control using my custom item template.

  • Update to my LINQ to SQL performance in VB.NET saga

    Hello,

    If you have  read my posts before where I was complaining about VB generated sub optimal SQL when using nullable columns in your where clauses, I came to the conclusion I was being silly and not using .Value on those nullable fields in my queries.

    I stumbled across this post today:

    http://blogs.msdn.com/vbteam/archive/2008/03/28/linq-to-sql-and-linq-to-entities-performance-improvements-tim-ng.aspx


    Looks like it was an issue in the end and not me being totally stupid :).

  • Book Review: Linq Quickly by N Satheesh Kumar

    This books title does not lie, it is LINQ and it is quickly. This book is an excellent introduction into the world of LINQ and also a great reference once you get your feet wet.

    The start of the book gives you a brief introduction into what LINQ is and also an introduction into the new features in C# 3.0. It covers things like anonyms types, object initializers, collection initializers, partial methods, implicitly typed local variables, extension methods, lambda expressions,  query expressions and also a small intro to expression trees.

    Then it covers LINQ to Objects, which gives you a good idea on how to use LINQ over your in memory objects, including arrays, collections, string and even text files. It shows you just how easy it is to do things that in the past would have been a lot harder to complete.

    Next up is LINQ to XML, this is a great introduction to this subject, it covers a great deal of information in regards to all the new LINQ to XML classes, how to create/update/delete XML documents using these new classes and methods. You are also shown the power you now have when you are querying XML and how easy it just is.

    The LINQ to SQL chapter is also an excellent reference if you would like to get your feet wet but would not like to be overwhelmed with information. There are plenty of good examples on how to begin using LINQ to SQL and the code samples provided make this very easy. It covers everything from Data Context, Attributes, Relationships, querying, data manipulation, using stored procedures and also all the other common query operators that you would use. There is also a chapter on LINQ to Datasets but as I never use datasets this was something I briefly skimmed over and did not digest.

    Finally the book provides a good chapter on Standard Query Operators, this is an excellent post reference once you are already in the world of LINQ, it is good to able to flick to be back, find what you need and see the function prototypes and even a code sample on how to use it. I still sometimes will flick to this part of the book to quickly reference things when I forget :P.

    All in all this was an excellent book and I would highly recommend it to anyone who would like to start out with LINQ but would like to get a quick introduction and be on their way to actually using it. This book provides just that and more


    Book Information:

  • A Templated ASP.NET RSS Feed Reader Control

    Update 20070330:

    By popular demand (well a couple people) I have included a sample project with everything needed to get started using this control.

    Basically just a sample web project, click here to get the zipped archive. You might notice things are done a little different, I include the System.ServiceModel.Syndication namespace on my page so that I can case the Container.DataItem to a SyndicationItem and access its properties that way, stops using Eval, but each to their own.


    Hope that makes it easier for some, will be including full source in future too :).

    Project Files:
    TemplatedRSSFeedReader.zip

    Thanks
    Stefan


    Update 20070319:

    Today I attended the Heros Happen event in Perth, and I learnt something very very cool, you see how I wrote my own classes and code to load the syndicated feed in, then used LINQ to XML to load that into my classes. During Dave Glovers presentation on WCF he had a sample in there that was building an RSS feed, and I could see he was using some classes to do so. What I then noticed is these classes are new in .NET 3.5 and will make creation of this control 100 times easier plug give us full support of the RSS 2.0 spec and allow us to access all feed proprties :) :) and will mean *removing* code and making things much simpler.

    Firstly we need to add a reference to the System.ServiceModel.Web assembley, this is where the magic is. Then add a using System.ServiceModel.Syndication; to the RSSReader.cs class, we then have access to these helper classes which allow us to easily read and create RSS 2.0 and ATOM 1.0 feeds, as I am only supporting RSS I will only use the RSS formatter. To read our feed we need to do the below:

    Firslty read the feed into an XMLReader:

    XmlReader reader = XmlReader.Create("http://weblogs.asp.net/stefansedich/rss.aspx");

    Then create an instance of the RSS20FeedFormatter and then make this read the data from the xmlreader:

    Rss20FeedFormatter feedFormatter = new Rss20FeedFormatter();
    feedFormatter.ReadFrom(reader);


    We now can get access to the feed by using feedFormatter.Feed, this gives us an instance of a SyndicationFeed class which gives us access to all items and properties of our feed. The only difference now is that as some properties are a little different accessing them is different.So instead of feed.Title you use feed.Title.Text instead. The good thing with this is, 1. We have removed the need to do this manually and 2. We have all properties that belong to an RSS feed.

    The updated RSSReader class is below with the code changes. You can now remove the Feed and FeedItem classes we created earlier as they are needed no more. It just goes to show we learn something new every day.....


    Code:

  • ASP.NET Ajax using a custom ViewManager to render paged data without updatepanels

    Sometimes you do not want the overhead of using an updatepanel, as each time you make a request it is posting more back than you might need, sure it can be powerful and easy to use but not always the most effective way Say you would like to be able to not use viewstate or postbacks but would like to get a result set of data that can be paged and you would like this totally client driven and to use the least ammount of overhead.

    Following on from Scott Guthries ViewManager (thanks Scott), and some ideas I have had lately to do alot more things client side and maybe stop using updatepanels. I have made a more generic ViewManager which I blogged about earlier, basically is just allows you to set properties of your control alot easier and can set any properties the control may have before you go ahead and render it. Don't flame for writing something already done, I find my version of the ViewManager easier to use, so thought I would share.

  • Different SQL between VB.NET and C# LINQ to SQL SOLVED!!

    Hi All,

    Following my previous post I have solved this issue. Somehow accidently I discovered that if the field has allow nulls set on it VB.NET will add the Where Coalesce in your query hence in my case slowing it down dramatically. It seems that C# does not do this. So finally I have my VB.NET sql comming out exactly the same as in C# simply by turning off allow nulls on my database column... Still seems like odd behaivour to me but for now it all works fine.


    Thanks
    Stefan

  • UserControl OutputCache and VaryByParam not working with postback!!

    Don't know if anyone has come across this before. But if you have a usercontrol that uses VaryByParam and you have it on a page and do a postback you will get the wrong cache item. Use the below test bed to see what I mean, this is following to my post for help on the asp.net forums, I then found this post which showed me it is an issue, following this I think I came up with a solution. That is to add a hidden field to my page with the name MenuID and populate that. Now on postback it seems to work fine, as VaryByParam="MenuID" seems to read the form var MenuID and gets the correct value hence fixing caching.
     

  • Fully Accessible And SEO Friendly Ajax Paging Using DataPager

    Hey All,

    Working on my current project I implemented paging using a listview and a datapager. I then decided it would be much nicer to use AJAX for my paging so wrapped all this up in an updatepanel. Next step was the issue when you would goto a page, select a product and hit the browser back button you would get the first page not the page you were last on. To fix this I simply implemented the ASP.NET AJAX Futures History control which allowed me to save my current page and restore this at a later time.

    Perfect I thought until I started thinking about SEO, now my product catalogue was dead to a search engine as it would only see the first page and not be able to do any further paging. To fix this I went about creating a SEO friendly linkbutton control (I have blogged about this a while back but this is the first time I used it in real life). Basically what the SEO Friendly linkbutton does is render a normal navigateURL and the postback as an onclick. This way with Javascript turned on you get a postback but without you have a normal URL, in my case I am passing the page # in my url like so: http://site.com/catalogue/page-XX/Whatever.aspx, I am using URL Rewriter.NET for my URL rewriting so making a nice URL for this was as simple as adding a new rule into my web.config.

    Firstly here is my custom SEOLinkButton control (Its in VB.NET as is my current project, I have a C# version too but will just post the VB.NET version unless requested):

    Public Class SEOLinkButton
        Inherits LinkButton

    #Region "Properties"

        Public Property NavigateURL() As String
            Get
                Return If(ViewState("NavigateURL") Is Nothing, "", ViewState("NavigateURL").ToString())
            End Get
            Set(ByVal value As String)
                ViewState("NavigateURL") = value
            End Set
        End Property

    #End Region

        Protected Overrides Sub AddAttributesToRender(ByVal writer As System.Web.UI.HtmlTextWriter)

            If (Me.Page IsNot Nothing) Then
                Me.Page.VerifyRenderingInServerForm(Me)
            End If

            Me.EnsureID()
            writer.AddAttribute(HtmlTextWriterAttribute.Id, Me.ClientID)

            If (Not String.IsNullOrEmpty(Me.CssClass)) Then
                writer.AddAttribute(HtmlTextWriterAttribute.Class, Me.CssClass)
            End If

            If (Not Me.Enabled) Then
                writer.AddAttribute(HtmlTextWriterAttribute.Disabled, "disabled")
            End If

            If (Not String.IsNullOrEmpty(Me.NavigateURL) AndAlso Me.Enabled) Then
                ' Set the href to be our navigateUrl.
                writer.AddAttribute(HtmlTextWriterAttribute.Href, Me.ResolveUrl(Me.NavigateURL))
            End If

            If (Me.Enabled) Then

                Dim customScript As String = Me.OnClientClick

                If (customScript.Length > 0 AndAlso Not customScript.EndsWith(";")) Then
                    customScript = customScript + ";"
                End If

                Dim opts As PostBackOptions = Me.GetPostBackOptions()
                Dim evt As String = Nothing

                If (opts IsNot Nothing) Then
                    evt = Me.Page.ClientScript.GetPostBackEventReference(opts)
                End If

                ' The onclick now becomes our postback, and the appended custom script.           
                writer.AddAttribute(HtmlTextWriterAttribute.Onclick, String.Format("{0}; {1} return false;", evt, customScript))

            End If

        End Sub

    End Class

  • Different SQL between C# and vb.net using LINQ to SQL causes performance issues

    Hi All,

    I am currently working on a project and we are using VB.NET, I am using LINQ to SQL for my data access. I have just implemented my search query and thought I would check the generated SQL's execution plan and found that the subtree cost was about 7.3. I know that I get different SQL between C# and VB.NET when using LINQ to SQL, as VB.NET seems to add a WHERE COALESCE instead of the straight WHERE that C# will do. In the past I did a quick check on a small query to see if it would make a difference and found that there was not a noticable one.

    Now having a larger more complex query I thought I would check the execution plan for the same query but written in C#, I now get a much smaller SQL query and the subtree cost drops from 7.3 to 0.1. A big difference IMO. Has anyone come across this before and what are your throughts on this. It baffles me that you would get such a difference in queries between the two languages.

  • Stop IE Flickering Between Pages

    I dont know if anyone has noticed but in IE when you click between pages in your site that have common elements i.e. a header. Your page will flicker for a brief moment. But in FireFox the page will not flicker and it will look smooth. I came across a fix for IE that will make this smooth just like in firefox.


    To use simply add the following 2 tags into your <head> section on your page:

  • Gotcha with linq and paging

    Hey All,

    Had a query which I was paging on the front end. I knew that a certain product was meant to be in my display but could not see it. But on page 2 a product would repeat itself. Odd, got into profiler and looked at the queries. The first page would get a select top 9 which would not do any orderby, the next page would have a query like so: SELECT ROW_NUMBER() OVER (ORDER BY [t15].[test], [t15].[ID], [t15].[CreatedDate] which was ordering by all my columns.

    So I added an orderby to my LINQ query which ordered my results by ProductName, then the paging was working as expected. Had another look in profiler and now I had what I expected.


    So a warning to all, make SQL Profiler your best friend because if you are not careful you could get spanked by LINQ.


    Thanks

    Stefan

  • Issues using HyperLink control with an image in a URL Rewriting scenario

    Hey All,

    I was using the HyperLink control in my page and added URL Rewriting to my page so that for example:

    http://site/test/test/default.aspx would be rewritten to http://site/default.aspx. I had a HyperLink control on the default page like so:

    <asp:HyperLink ID="hl1" runat="server" NavigateUrl="~/test.aspx" ImageUrl="~/test.jpg" Text="A"></asp:HyperLink>

    And I was getting the dreaded error: Cannot use a leading .. to exit above the top directory...

    Looking into this a little more if you remove the ImageURL property or even set it to be /test.jpg it will work fine, so conluded it must be something to be with the ImageUrl property in the control. Digging into reflector it looks like that when the HyperLink control renders it creates a new Image object and sets the ImageUrl of that to be ResolveClientUrl(url), internally the Image control also does a ResolveClientUrl again on that URL and I think this is where the issue is.

    My solution was to create a FixUrl method in my utility class which would convert replace ~/ in a url with the current application base path hence giving me an absolute URL. This is also handy to use in your pages to set the urls of your CSS, JS etc.


    Public Shared Function FixUrl(ByVal inURL As String) As String
            Return If(inURL.StartsWith("~"), _
                      HttpContext.Current.Request.ApplicationPath & inURL.Substring(1), _
                      inURL).Replace("//", "/")
    End Function


    I would now assign my ImageUrl property in code i.e. img1.ImageUrl = FixURL("~/test.jpg") and this now works well.


    If anyone has come past this before suggestions or ideas they would be appreciated.


    Thanks

    Stefan

  • EventValidation issues with asp.net ajax and FireFox caching causing issues...

    Was having some wierd issues with asp.net ajax in firefox. If for example you put a textbox and a button in an updatepanel and put in a value and click the button. Then you hit F5, in IE the value will be gone, but in FireFox the value is still there. This is due to firefox caching input values. The only way to clear that textbox in FF is to do a ctrl + F5. I had an issue in a paged datagrid where if you paged to say page 5, hit F5 it would be at page 1, hit nextpage and it would be back at 5. This had me stumped until I realised that firefox is caching the values and most likely the __VIEWSTATE hidden field is being cached and this is causing the issues. So I added this to my page load:

    Response.Cache.SetNoStore()


    This made firefox work but this turns off client caching which might not be a good idea. A developer (Steve) at work had a form with a button and textbox which in FF would not remember the value, this was a real WTF moment. I got his code and double checked the differences between them. The only thing different was that in his form he had autocomplete="off" set on the form due to using an autocomplete extender. I added this to my form and presto it was working perfectly. This was ok but you might not want to turn autocomplete off for your whole form so what can we do:

    Solution:


    Thinking about this I thought of what fields could affect this. Looking at a page you have the following hidden fields:

    __VIEWSTATE, __EVENTTARGET, __EVENTARGUMENT, __EVENTVALIDATION.


    I decided to try and turn of autocomplete for only these fields using some script at the bottom of my page:

    <script>
           function setAutoCompleteOff(id) {
                var elem = document.getElementById(id);
                if(elem) {
                    elem.setAttribute('autocomplete', 'off');
                }           
            }
           
            setAutoCompleteOff('__VIEWSTATE');
            setAutoCompleteOff('__EVENTTARGET');
            setAutoCompleteOff('__EVENTARGUMENT');
            setAutoCompleteOff('__EVENTVALIDATION');
    </script>


    Then I turned autocomplete back on on the form, and gave it a go, and to my supprise it worked perfectly. Now FF was not using sending over the cached values on hitting F5 and was using the original values. This meant my page works fine. One more thing is you can now turn on EnableEventValidation on your page and it seems to work fine now.

  • PNG Fix Component

    Needing a solution to fix transparent PNG in IE6 I came to start using one of the many javascript based solutions to do this. But when it came time to use ajax and populating new images in my postbacks this obviously broke. So I created a custom ASP.NET Component to help me do this...