Contents tagged with .NET

  • NHibernate Pitfalls: Deletes

    This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.

    While I was writing Deleting Entities in NHibernate, I noticed that actually it referred some pitfalls concerning deleting, so I decided to add them to the proper collection.

    There are several ways to delete entities in NHibernate, as you can see in the referenced post. The problems with each approach are:

    • Using Executable HQL: no cascade to related associations occurs, no events are raised;
    • Using Delete with an entity proxy: forces loading of all cascaded lazy associations before deleting; requires a Flush to apply changes (if it needs to be explicit or not depends on you flush settings);
    • Using Delete with a query string: all items are loaded into the session (not a single DELETE statement), no cascade occurs, no events are raised, no notification about the number of affected records and also requires a flush.

    Read more...

  • NHibernate Pitfalls: Get and Filters

    This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.

    This was suggested a long time ago by Kelly Brownsberger (@kbrowns). What happens is, even if you have filters defined, they are not applied on a call to ISession.Get<T>(). This is by design: you are explicitly asking for an entity with some id, so NHibernate just returns you that. On the other hand, static where restrictions defined at the entity level still apply.

    Read more...

  • NHibernate Pitfalls: Criteria and Collections of Non-Entities

    This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.

    Criteria API – and QueryOver, for that matter, which is just a strongly-typed wrapper around Criteria – cannot work with collections of non-entities: elements, components or dictionaries. If you need to work with those, you need to use one of the other APIs – LINQ, HQL or SQL.

    Read more...

  • Deleting Entities in NHibernate

    This post was motivated by a conversation with Salvador Gascon (@salvadorgascon). Might even go to the pitfalls section… Anyway, the problem is: how many ways there are to delete an entity in NHibernate? And what are the advantages/disadvantages of each?

    First, we have the classic one, using ISession.Delete(), which all NHibernate developers should be familiar with:

       1: var product = session.Get<Product>(id);
       2:  
       3: session.Delete(product);
       4:  
       5: session.Flush();

    Using ISession.Get<T>(), you force an entity – and all of its non-lazy associations and properties – to be loaded from the database. When you delete it, all associations marked for cascade delete will also be deleted.

    If you don’t want to load the entity from the database in order to delete it, you can use ISession.Load<T>(), for entities marked as lazy, this will return a proxy instead:

       1: var product = session.Load<Product>(id);
       2:  
       3: session.Delete(product);
       4:  
       5: session.Flush();

    Do note, however, that when Delete is called, the entity will still be loaded, as well as all its non-lazy associations. Flushing is required.

    For better performance, we can use Executable HQL:

       1: session.CreateQuery("delete from Product p where p.ProductId = :id")
       2: .SetParameter("id", id)
       3: .ExecuteUpdate();

    This will translate to a single plain old SQL DELETE command, so no entity will be loaded into the session. This has a big disadvantage, though: no cascade deletes will occur. This means that you may get exceptions due to foreign key violations. A good thing is that it returns the number of deleted records.

    Another way to delete is through an overload of the Delete method:

       1: session.Delete(String.Format("from Product p where p.ProductId = {0}", id));
       2:  
       3: session.Flush();

    In this case, we are providing the id in the query string, which is not good, mainly for performance reasons – with NHibernate HQL, SQL injections are much more difficult to do. A better alternative is to use positional parameters:

       1: session.Delete("from Product p where p.ProductId = ?", id, NHibernateUtil.Int32);

    In this case, together with the id, we also need to supply its type. Does not cascade nor return the number of deleted records.

    Read more...

  • NHibernate Pitfalls: HQL Delete Does Not Cascade

    This is part of a series of posts about NHibernate Pitfalls. See the entire collection here.

    When you issue an HQL delete statement over an entity, you may be surprised to find out that it will not cascade to any configured associations it may have:

       1: session.CreateQuery("delete from Order o where o.Id = :id").SetParameter("id", 10).ExecuteUpdate();

    If you really want to cascade associations, you will have to load the entity explicitly and then call ISession.Delete() upon it.

    Read more...

  • Entity Framework Pitfalls – Date/Time Operations

    When using Entity Framework, you cannot perform date/time operations as you would normally do in .NET/LINQ to Objects. For instance, the following query throws an exception:

       1: ctx.Projects.Select(x => new { ElapsedTime = DateTime.Now - x.Start }).ToList();

    Instead, you need to use the static methods in SqlFunctions, like DateDiff:

       1: ctx.Projects.Select(x => new { ElapsedTime = SqlFunctions.DateDiff("HOUR", x.Start, DateTime.Now) }).ToList();

    For a full description of DateDiff’s first parameter, refer to http://msdn.microsoft.com/en-us/library/ms189794.aspx.

    If you want to achieve the same result, that is, return a TimeSpan, you need to use LINQ to Objects at the end:

       1: ctx.Projects.Select(x => new { ElapsedTime = SqlFunctions.DateDiff("HOUR", x.Start, DateTime.Now) }).ToList().Select(x => new { ElapsedTime = TimeSpan.FromHours((Double)x.ElapsedTime) }).ToList();

    Read more...

  • NHibernate 4.0

    Recently, the NHibernate team released NH 4.0. You can get it as a NuGet package from https://www.nuget.org/packages/nhibernate, as a ZIP from http://sourceforge.net/projects/nhibernate/ or as source code from https://github.com/nhibernate/nhibernate-core. The full release notes are available at https://github.com/nhibernate/nhibernate-core/blob/master/releasenotes.txt, but here are some highlights.

    One of its most important features is that it no longer needs Iesi.Collections for most common uses: where you would declare a set as Iesi.Collections.Generic.ISet<T>, now you use System.Collections.Generic.ISet<T>. However, if you want to use the order-by attribute of sets, you still need Iesi.Collections, because NHibernate will still use it (LinkedHashSet<T>). All of the public APIs that used Iesi.Collections.Generic.ISet<T> or Iesi.Collections.ISet now use System.Collections.Generic.ISet<T>, this includes all the event handler methods.

    Method SaveOrUpdateCopy of ISession was removed and Merge should be used instead.

    The ManagedWebSessionContext context class was removed and the managed_web alias for XML configuration is no longer supported. Now you should use WebSessionContext and web.

    The Firebird driver was removed and replaced for FirebirdClientDriver. ASA10ClientDriver, ASAClientDriver and SQLiteDriver were removed in favor of SybaseSQLAnywhereDriver, SybaseAsaClientDriver and SQLite20Driver, respectively. A managed ODP.NET driver for Oracle is now available (OracleManagedDataClientDriver).

    Sql2012Dialect was introduced and now properly pages records. Also added Ingres9Dialect. SybaseASADialect (use SybaseSQLAnywhere10Dialect),

    MySQL now supports batching inserts (MySqlClientBatchingBatcher).

    There have also been some breaking changes in the IProjection interface because the IEnhancedProjection interface was removed and its methods moved to IProjection.

    Misspelled class AdoNetWithDistrubtedTransactionFactory is now AdoNetWithDistributedTransactionFactory.

    NHibernate XML configuration on App.config or Web.config now accepts attribute linqtohql.generatorsregistry.

    On mapping by code, you can now specify the class of a one-to-one endpoint (IOneToOneMapper.Class) and an optional table check clause (IClassMapper.Check). Also available are enhanced id generators Enhanced Sequence (Generators.EnhancedSequence) and Enhanced Table (Generators.EnhancedTable). You can now pass a dictionary to IGeneratorMapper.Params, no need to use anonymous types, which is better for dynamic code.

    QueryOver projections now support Math.Round() to round up floating point numbers.

    DefaultIfEmpty is now supported with GroupBy and Distinct is now supported with anonymous types.

    Finally, all static type fields in NHibernateUtil are now declared as their exact type, not a base class, which is better for using in mapping by code.

    Read more...

  • ASP.NET Web Forms Extensibility: Page Parser Filters

    Introduction

    ASP.NET includes a valuable yet not well known extension point called the page parser filter. I once briefly talked about it in the context of SharePoint, but I feel a more detailed explanation is in order.

    A page parser filter is a class with a public parameterless constructor that inherits from PageParserFilter and is registered on the Web.config file, in the pages section, pageParserFilterType attribute. It is called when ASP.NET is compiling a page, the first time it is called, for every page. There can be only one page parser filter per web application.

    Parser

    Why is it a parser? Well, it parses – or, better, receives a notification for - every control declared on the markup of a page (those with runat=”server” or contained inside of), as well as all of the page’s directives (<%@ … %>). The control declarations include all of its attributes and properties, the recognized control type and any complex properties that the markup contains. This allows us to do all kinds of crazy stuff:

    • Inspect, add and remove page directives;
    • Setting the page’s compilation mode;
    • Insert or remove controls or text literals dynamically at specific places;
    • Add/change/remove a control’s properties or attributes;
    • Even (with some reflection magic) change a control’s type or tag.


    So, how do we all this? First, the parser part. We can inspect all page directives by overriding the PreprocessDirective method. This is called for all page directives:

       1: public override void PreprocessDirective(String directiveName, IDictionary attributes)
       2: {
       3:     if (directiveName == "page")
       4:     {
       5:         //make a page asynchronous
       6:         attributes["async"] = "true";
       7:     }
       8:  
       9:     base.PreprocessDirective(directiveName, attributes);
      10: }

    The page’s compilation mode is controlled by GetCompilationMode:

       1: public override CompilationMode GetCompilationMode(CompilationMode current)
       2: {
       3:     return (base.GetCompilationMode(current));
       4: }

    As for adding controls dynamically, we make use of the ParseComplete method:

       1: public override void ParseComplete(ControlBuilder rootBuilder)
       2: {
       3:     if (rootBuilder is FileLevelPageControlBuilder)
       4:     {
       5:         this.ProcessControlBuilder(rootBuilder);
       6:     }
       7:  
       8:     base.ParseComplete(rootBuilder);
       9: }
      10:  
      11: private void ProcessControlBuilder(ControlBuilder builder)
      12: {
      13:     this.ProcessControlBuilderChildren(builder);
      14:  
      15:     if (builder.ControlType == typeof(HtmlForm))
      16:     {
      17:         //add a Literal control inside the form tag
      18:         var literal = ControlBuilder.CreateBuilderFromType(null, builder, typeof(Literal), "asp:Literal", "literal", new Hashtable { { "Text", "Inserted dynamically I" } }, -1, null);
      19:         builder.AppendSubBuilder(literal);
      20:  
      21:         //add an HTML snippet inside the form tag
      22:         builder.AppendLiteralString("<div>Inserted dynamically II</div>");
      23:     }
      24: }
      25:  
      26: private void ProcessControlBuilderChildren(ControlBuilder parentBuilder)
      27: {
      28:     foreach (var builder in parentBuilder.SubBuilders.OfType<ControlBuilder>())
      29:     {
      30:         this.ProcessControlBuilderChildren(builder);
      31:     }
      32: }

    Same for changing a control’s properties:

       1: private static readonly FieldInfo simplePropertyEntriesField = typeof(ControlBuilder).GetField("_simplePropertyEntries", BindingFlags.Instance | BindingFlags.NonPublic);
       2:  
       3: private void SetControlProperty(ControlBuilder builder, String propertyName, String propertyValue)
       4: {
       5:     var properties = (simplePropertyEntriesField.GetValue(builder) as IEnumerable);
       6:  
       7:     if (properties == null)
       8:     {
       9:         properties = new ArrayList();
      10:         simplePropertyEntriesField.SetValue(builder, properties);
      11:     }
      12:  
      13:     var entry = properties.OfType<SimplePropertyEntry>().SingleOrDefault(x => x.Name == propertyName) ?? simplePropertyEntryConstructor.Invoke(null) as SimplePropertyEntry;
      14:     entry.Name = propertyName;
      15:     entry.UseSetAttribute = (builder.ControlType != null && builder.ControlType.GetProperties().Any(x => x.Name.Equals(propertyName, StringComparison.OrdinalIgnoreCase)) == false);
      16:     entry.PersistedValue = propertyValue;
      17:     entry.Value = entry.PersistedValue;
      18:     entry.Filter = String.Empty;
      19:  
      20:     if (properties.OfType<SimplePropertyEntry>().Any(x => x.Name == propertyName) == false)
      21:     {
      22:         (properties as ArrayList).Add(entry);
      23:     }
      24: }
      25:  
      26: private void ProcessControlBuilder(ControlBuilder builder)
      27: {
      28:     if (typeof(IEditableTextControl).IsAssignableFrom(builder.ControlType) == true)
      29:     {
      30:         this.SetControlProperty(builder, "Text", "Injected dynamically!");
      31:     }
      32:  
      33:     this.ProcessControlBuilderChildren(builder);
      34: }

    And even changing the control’s output tag or instance type:

       1: private static readonly FieldInfo controlTypeField = typeof(ControlBuilder).GetField("_controlType", BindingFlags.Instance | BindingFlags.NonPublic);
       2: private static readonly FieldInfo tagNameField = typeof(ControlBuilder).GetField("_tagName", BindingFlags.Instance | BindingFlags.NonPublic);
       3:  
       4: private void SetControlType(ControlBuilder builder, Type controlType)
       5: {
       6:     controlTypeField.SetValue(builder, controlType);
       7: }
       8:  
       9: private void SetTagName(ControlBuilder controlBuilder, String tagName)
      10: {
      11:     tagNameField.SetValue(controlBuilder, tagName);
      12: }
      13:  
      14: private void ProcessControlBuilder(ControlBuilder builder)
      15: {
      16:     if (builder.TagName != null)
      17:     {
      18:         this.SetTagName(builder, builder.TagName.ToUpper());
      19:     }
      20:  
      21:     if (builder.ControlType == typeof(MyControl))
      22:     {
      23:         this.SetControlType(builder, typeof(MyDerivedControl));
      24:     }
      25:  
      26:     this.ProcessControlBuilderChildren(builder);
      27: }

    Why would we want to change a control’s type? Well, thing about generics, for once.

    Filter

    And now the filtering part: why is it a filter? Because it allows us to filter and control a number of things:

    • The allowed master page, base page class and source file;
    • The allowed controls;
    • The total number of controls allowed on a page;
    • The total number of direct and otherwise references on a page;
    • Allow or disallow code and event handler declarations;
    • Allow or disallow code blocks (<%= … %>, <%: … %>, <% … %>);
    • Allow or disallow server-side script tags (<script runat=”server”>…</script>);
    • Allow, disallow and change data binding expressions (<%# … %>);
    • Add, change or remove event handler declarations.


    All of the filtering methods and properties described below return a Boolean flag and its base implementation may or may not be called, depending on the logic that we want to impose.

    Allowing or disallowing a base page class is controlled by the AllowBaseType method (the default is to accept):

       1: public override Boolean AllowBaseType(Type baseType)
       2: {
       3:     return (baseType == typeof(MyBasePage));
       4: }

    For master pages, user controls or source files we have the AllowVirtualReference virtual method (again, the default is true):

       1: public override Boolean AllowVirtualReference(String referenceVirtualPath, VirtualReferenceType referenceType)
       2: {
       3:     if (referenceType == VirtualReferenceType.Master)
       4:     {
       5:         return (referenceVirtualPath == "AllowedMaster.Master");
       6:     }
       7:     else if (referenceType == VirtualReferenceType.UserControl)
       8:     {
       9:         return (referenceVirtualPath != "ForbiddenControl.ascx");
      10:     }
      11:  
      12:     return (base.AllowVirtualReference(referenceVirtualPath, referenceType));
      13: }

    Controls are controlled (pun intended) by AllowControl, which also defaults to accept:

       1: public override Boolean AllowControl(Type controlType, ControlBuilder builder)
       2: {
       3:     return (typeof(IForbiddenInterface).IsAssignableFrom(controlType) == false);
       4: }

    This may come in handy to disallow the usage of controls in ASP.NET MVC ASPX views!

    The number of controls and dependencies on a page is defined by NumberOfControlsAllowed, NumberOfDirectDependenciesAllowed and TotalNumberOfDependenciesAllowed. Interesting, the default for all these properties is 0, so we have to return –1:

       1: public override Int32 NumberOfControlsAllowed
       2: {
       3:     get
       4:     {
       5:         return (-1);
       6:     }
       7: }
       8:  
       9: public override Int32 NumberOfDirectDependenciesAllowed
      10: {
      11:     get
      12:     {
      13:         return (-1);
      14:     }
      15: }
      16:  
      17: public override Int32 TotalNumberOfDependenciesAllowed
      18: {
      19:     get
      20:     {
      21:         return (-1);
      22:     }
      23: }

    Direct dependencies are user controls directly declared in the page and indirect ones are those declared inside other user controls.

    Code itself, including event handler declarations, are controlled by AllowCode (default is true):

       1: public override Boolean AllowCode
       2: {
       3:     get
       4:     {
       5:         return (true);
       6:     }
       7: }

    If we want to change a data binding expression, we resort to ProcessDataBindingAttribute, which also returns true by default:

       1: public override Boolean ProcessDataBindingAttribute(String controlId, String name, String value)
       2: {
       3:     if (name == "Text")
       4:     {
       5:         //Do not allow binding the Text property
       6:         return (false);
       7:     }
       8:  
       9:     return (base.ProcessDataBindingAttribute(controlId, name, value));
      10: }

    For intercepting event handlers, there’s the ProcessEventHook, which likewise returns true by default:

       1: public override Boolean ProcessEventHookup(String controlId, String eventName, String handlerName)
       2: {
       3:     if (eventName == "SelectedIndexChanged")
       4:     {
       5:         //Remove event handlers for the SelectedIndexChanged event
       6:         return (false);
       7:     }
       8:  
       9:     return (base.ProcessEventHookup(controlId, eventName, handlerName));
      10: }

    And finally, for code blocks, server-side scripts and data binding expressions, there’s the ProcessCodeConstruct method, which likewise also allows everything by default:

    Conclusion

    This was in no means an in-depth description of page parser filters, I just meant to give you an idea of its (high) potential. It is very useful to restrict what end users can place on their pages (SharePoint style) as well as for adding dynamic control programmatically in specific locations of the page, before it is actually built.

    As usual, let me hear your thoughts! Winking smile

    Read more...

  • NHibernate Succinctly

    It’s with great pleasure that I see the release of NHibernate Succinctly, a book that I wrote for Syncfusion’s Succinctly series! It’s my second title, more to come! Winking smile

    Like Entity Framework Code First Succinctly, this book has something for the beginner as well as for more advanced users. Unlike EFCFS, it covers the current version of NHibernate.

    My good friend Zoran Maksimovic (@zoranmax) was the technical reviewer and besides him, I also want to thank everyone at Syncfusion: Hillary Bowling, Darren West, Tres Watkins and Graham High for their feedback and support, and for the opportunity they gave me. Of course, my coleagues at Critical, Pedro Gomes (@pedromvgomes) and Marco Carreira, and also my old friend Tiago Andrade, who also conducted reviews, cannot be forgotten as well!

    Go ahead, grab your copy and let me know what you think!

    By the way, it might be interesting to write something about my experience as an author… Any of you Succinctly authors out there would like to share your experience? Write me a line or comment here! Thanks!

    Read more...