Saturday, October 13, 2012

QueryAll in RavenDB

RavenDB is an awesome NoSQL product, if you don’t know it, I strongly suggest you take a look at it. It tries to be safe by default, which is at great idea, but sometimes you just need to get more than 1024 documents. Yes, this could indicate a misuse of RavenDB, but again sometimes it is needed, and the only way to do this in RavenDB is to use paging.

It is easy enough to do paging, but it requires some code and could easily be implemented in an extension method like this:

It extends an IRavenQueryable with a QueryAll method which uses paging to get all results of the query.

It should be use with great care, this totally circumvents the safe-by-default design implemented in RavenDB, and the results are iterated when calling QueryAll, so after this call the database aren’t hit anymore. Use it as you please, but be careful, it can ruin performance and should only be used when strictly necessary.

Wednesday, April 11, 2012

Inside the MvcSiteMapProvider - Part 5: The ISiteMapNodeUrlResolver

The ISiteMapNodeUrlResolver defines how URLs are resolved. The default URL resolver are fine most of the time, as it uses the different ways to resolve URLs built-in to ASP.NET MVC. But sometimes it is necessary to create a custom resolver, for example if all URL are required to be lower or upper case. In this post I’ll try to explain exactly how the default resolver works and how to implement a custom resolver.

Tuesday, April 10, 2012

Inside the MvcSiteMapProvider - Part 4: The IAclModule

The IAclModule extension point in , are just like the ISiteMapVisibilityProvider very useful and easily implemented. It allows you to control which nodes are accessible to users. The default module checks for [Authorize] attributes on action methods and the roles attribute defined in the sitemap XML. The documentation lacks some information about the role attribute, and some about the creation of the actual module, this will be addressed in this post.

Monday, April 9, 2012

Inside the MvcSiteMapProvider - Part 3: The ISiteMapVisibilityProvider

This part is all about the ISiteMapVisibilityProvider in the . The usage is well described on the wiki page, and is very easy to use.
Ever wanted to only show specific sitemap nodes to authenticated users or only unauthenticated? With a specific role? All this can be done in 5 minutes with the ISiteMapVisibilityProvider.

Wednesday, April 4, 2012

Inside the MvcSiteMapProvider - Part 2: Dynamic node providers

Dynamic node providers gives you the ability to add dynamically generate nodes to the sitemap, fx. pages generated from a database. This is one of the most used extension points in the , and it is also easy to implement.

Inside the MvcSiteMapProvider - Part 1

I have recently worked a lot with the MvcSiteMapProvider, a great project created by Maarten Balliauw, which greatly simplifies navigation and sitemap.xml generation. But how is it done? This is of great importance to good performance, wrongly implemented it can make you site pretty slow.
Because of this I decided to create a series of in-depth posts about the internals of the MvcSiteMapProvider, and give some advices on how to improve performance. The first part is about how the main part of the provider is implemented.

Tuesday, February 14, 2012

How to get changed properties for an entity in Entity Framework

Sometimes it can be useful to find exactly which entities that have been changed before saving to the database. The most basic for check for changes it to look at the EntityState property, but this does not indicate what properties that have been changed.

To get these changes we have to use the ObjectStateManager on ObjectContext. The ObjectStateManager handles the state of all entities, and can supplied a lot of other different state information about the entities.

First we always need to get the ObjectStateEntry for the entity, this a done by calling ObjectStateManager.GetObjectStateEntry.

TestEntities entities = new TestEntities();

// Query for entity and make some changes

// To get the object state entry
var stateEntry = entities.ObjectStateManager.GetObjectStateEntry(changedEntity);

To check which properties that have changed we just do

IEnumerable modifiedProperties = stateEntry.GetModifiedProperties();

We can also get all the original and current values for the entity using

CurrentValueRecord currentValues = stateEntry.CurrentValues;
DbDataRecord originalValues = stateEntry.OriginalValues;

These two objects can are accessed by column ordinal, which you may or may not know before, but luckily there is a method to get the ordinal from a column name. To get the current and/or original value for an entity, do the following

var currentValue = currentValues.GetValue(currentValues.GetOrdinal(propertyName));
var originalValue = originalValues.GetValue(originalValues.GetOrdinal(propertyName));

Not all properties are correctly marked as changed

When using this method to generate a custom audit trail, I discovered a weird behavior in Entity Framework. Everything but the primary key, are marked as modified even though it only was "changed" to the original value. And this does not work in an audit trail.

There are two ways to solve this either manual check if a property actually has been changed, or change to generate classes for the entities. The last solution are described in my previous post, Entity Framework should only mark really updated properties as modified

The other solution is to check if the current value equals the original value using the methods described above. An example could be

var stateEntry = objectStateManager.GetObjectStateEntry(entity);
var currentValues = stateEntry.CurrentValues;
var originalValues = stateEntry.OriginalValues;
var modifiedProperties = stateEntry.GetModifiedProperties();
foreach (string modifiedProperty in modifiedProperties)
{
  var currentValue = currentValues.GetValue(currentValues.GetOrdinal(modifiedProperty));
  var originalValue = originalValues.GetValue(originalValues.GetOrdinal(modifiedProperty));
  if (originalValue.Equals(currentValue))
  {
    // Value not changed
  }
  else
  {
    // Value changed
  }
}

Monday, February 13, 2012

Entity Framework should only mark really updated properties as modified

Today I discovered a weird behavior in Entity Framerwork. When I set the value of an entity to the same value as in the database, it would still say the value had been changed. This is the case of all values except the primary key value.
This means that we would unnecessary update the value on SaveChanges(). How could we change this behavior? I went to Google for an answer and found one on StackOverflow, but unfortunately it can't find it again.

But basically the fix is to edit the T4 template used to generate to entities. The easiest way to do this is to change the Code Generation item by right clicking on the EF design surface, click "Add Code Generation Item..." and choose "ADO.NET EntityObject Generator". This adds a T4 template to the project, which we can edit to check if the value are the same as the original.
Somewhere in the template in my case at line 552, in the .tt file, the following part needs to be changed.
/// <summary>
/// <#=SummaryComment(primitiveProperty)#>
/// </summary><#=LongDescriptionCommentElement(primitiveProperty, 1)#>
[EdmScalarPropertyAttribute(EntityKeyProperty=<#=code.CreateLiteral(ef.IsKey(primitiveProperty))#>, IsNullable=<#=code.CreateLiteral(ef.IsNullable(primitiveProperty))#>)]
[DataMemberAttribute()]
<#=code.SpaceAfter(NewModifier(primitiveProperty))#><#=Accessibility.ForProperty(primitiveProperty)#> <#=code.Escape(primitiveProperty.TypeUsage)#> <#=code.Escape(primitiveProperty)#>
{
  <#=code.SpaceAfter(Accessibility.ForGetter(primitiveProperty))#>get
  {
            if (ef.ClrType(primitiveProperty.TypeUsage) == typeof(byte[]))
      {

    return StructuralObject.GetValidValue(<#=code.FieldName(primitiveProperty)#>);

      }
      else
      {
#>
    return <#=code.FieldName(primitiveProperty)#>;
<#+
      }
#>
  }
  <#=code.SpaceAfter(Accessibility.ForSetter((primitiveProperty)))#>set
  {
<#+
  if (ef.IsKey(primitiveProperty))
    {
      if (ef.ClrType(primitiveProperty.TypeUsage) == typeof(byte[]))
      {
#>
    if (!StructuralObject.BinaryEquals(<#=code.FieldName(primitiveProperty)#>, value))
<#+
      }
      else
      {
#>
    if (<#=code.FieldName(primitiveProperty)#> != value)
<#+
      }
#>
    {
<#+
  PushIndent(CodeRegion.GetIndent(1));
    }
#>
    <#=ChangingMethodName(primitiveProperty)#>(value);
    ReportPropertyChanging("<#=primitiveProperty.Name#>");
    <#=code.FieldName(primitiveProperty)#> = StructuralObject.SetValidValue(value<#=OptionalNullableParameterForSetValidValue(primitiveProperty, code)#>);
    ReportPropertyChanged("<#=primitiveProperty.Name#>");
    <#=ChangedMethodName(primitiveProperty)#>();
<#+
  if (ef.IsKey(primitiveProperty))
    {
  PopIndent();
#>
    }
<#+
    }
#>
  }
}


The fix lies in removing the
if (ef.IsKey(primitiveProperty))
statement to always check if the value are different. The solution is to replaces to code block above with this code block:

/// <summary>
/// <#=SummaryComment(primitiveProperty)#>
/// </summary><#=LongDescriptionCommentElement(primitiveProperty, 1)#>
[EdmScalarPropertyAttribute(EntityKeyProperty=<#=code.CreateLiteral(ef.IsKey(primitiveProperty))#>, IsNullable=<#=code.CreateLiteral(ef.IsNullable(primitiveProperty))#>)]
[DataMemberAttribute()]
<#=code.SpaceAfter(NewModifier(primitiveProperty))#><#=Accessibility.ForProperty(primitiveProperty)#> <#=code.Escape(primitiveProperty.TypeUsage)#> <#=code.Escape(primitiveProperty)#>
{
  <#=code.SpaceAfter(Accessibility.ForGetter(primitiveProperty))#>get
  {
<#+             if (ef.ClrType(primitiveProperty.TypeUsage) == typeof(byte[]))
      {
#>
    return StructuralObject.GetValidValue(<#=code.FieldName(primitiveProperty)#>);
<#+
      }
      else
      {
#>
    return <#=code.FieldName(primitiveProperty)#>;
<#+
      }
#>
  }
  <#=code.SpaceAfter(Accessibility.ForSetter((primitiveProperty)))#>set
  {
<#+
      if (ef.ClrType(primitiveProperty.TypeUsage) == typeof(byte[]))
      {
#>
    if (!StructuralObject.BinaryEquals(<#=code.FieldName(primitiveProperty)#>, value))
<#+
      }
      else
      {
#>
    if (<#=code.FieldName(primitiveProperty)#> != value)
    {
<#+
  PushIndent(CodeRegion.GetIndent(1));
    }
#>
    <#=ChangingMethodName(primitiveProperty)#>(value);
    ReportPropertyChanging("<#=primitiveProperty.Name#>");
    <#=code.FieldName(primitiveProperty)#> = StructuralObject.SetValidValue(value<#=OptionalNullableParameterForSetValidValue(primitiveProperty, code)#>);
    ReportPropertyChanged("<#=primitiveProperty.Name#>");
    <#=ChangedMethodName(primitiveProperty)#>();
<#+
  PopIndent();
#>
    }
  }
}