Wednesday, September 10, 2014

Static Member in C#

A good explanation and examples are found at http://csharp.net-tutorials.com/classes/static-members/

public class Rectangle
{
    private int width, height;
    public Rectangle(int width, int height)
    {
        this.width = width;
        this.height = height;
    }
    public void OutputArea()
    {
        Console.WriteLine("Area output: " + Rectangle.CalculateArea(this.width, this.height));
    }
    public static int CalculateArea(int width, int height)
    {
        return width * height;
    }
}


I like the author's example using Rectangle.CalculateArea( this.width, this.height) as an example of using a static member in a non-static class.

Thursday, September 4, 2014

Entity Framework : Update only changed fields instead of all fields

If we follow the Entity Framework's general approach to edit, it would be something similar to this.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "FacilityID, FacilityName, AddressLine1, AddressLine2")] 
Facility facility)
{
  ...
  if( ModelState.IsValid )
  {
    db.Entry(facility).State = EntityState.Modified;
    db.SaveChanges();
    return RedirectToAction("Index");
  }
..
}

The code in the above treats all fields as `Modified` and saves all field data into the database whether the old and new value of each field is the same or different.

However, there are times that we need to update only certain fields, instead of updating all fields data. The above example would update all field data (FacilityName, AddressLine1, AddressLine2), even when only AddressLine1 was changed by user. In order to save only the changed field data into the database, we can try the following approach: compare each field's value between old and new first and perform update only on the ones that are different.
using System.Data.Entity.Infrastructure;
...
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(
  [Bind(Include = "FacilityID, FacilityName, AddressLine1, AddressLine2")] 
   Facility facility)
{
  ...
  if( ModelState.IsValid)
  {
    db.Facilities.Attach( facility );
    DbEntityEntry entry = db.Entry( facility );
    foreach( var propertyName in entry.OriginalValues.PropertyNames )
    {
      // Get the old field value from the database.
      var original = entry.GetDatabaseValues().GetValue<object>(propertyName);
      // Get the current value from posted edit page.
      var current = entry.GetCurrentValues.GetValue<object>(propertyName);
      if(!object.Equals(original, current))
      {
        entry.Property( propertyName ).isModified = true;
      }
    }
    db.SaveChanges();
  }
}


Here we first get all property names (field names) and inspect each property's old and new values. Old values are retrieved from the database. New values are ones submitted by user through post.
// Get the old field value from the database.
var original = entry.GetDatabaseValues().GetValue<object>(propertyName); 
// Get the current value from posted edit page.
var current = entry.GetCurrentValues().GetValue<object>(propertyName); 
When the two values of original and current of a property are not equal,
that property will be assigned `IsModifed = true`, and its current value will be saved into the database.

On the other hand, if current field's values exist in the database already, those field values will be skipped while db.SaveChanges() is performed .


Remove containment from draggable jQuery UI Dialog

By default,  a draggable jQuery UI Dialog has containtment such that when you drag the dialog, you will be restricted by the browser's window. While comparing this default behavior against SharePoint's modal detail/edit dialog, SharePoint's dialog feels more user friendly and natural, because it lets users drag the dialog beyond the browser window. It simply feels natural to be able to move around the modal dialog outside browser window so that you can view the underlying main page's data as much as possible.

To remove containment from a draggable jQuery UI Dialog, try the following.
The trick is to use draggable's containtment property via widget of the dialog.

// Button that opens the dialog and a div to be used as the dialog
<input type="button" id="btnOpenDialog" value="Open Dialog" />
<div id="dialog"></div>
<script type="text/javascript">
  var myDialog = null; // global variable
  $(function(){
    $('#btnOpenDialog').on('click', function(){

      // Step 1.
      // Get the dialog ready.
      myDialog = $('#dialog').dialog({
        autoOpen: false, modal: true, resizable: true, width: 400, 
        buttons: {
          OK: function(){ // perform some actions ...},
          Cancel: function(){ $(this).dialog('close'); } // close the dialog 
        }
      });
      
      // Step 2.
      // `myDialog` is a global variable and has a reference to the dialog.
      // Use `myDialog` to remove containment from the dialog.
      myDialog.dialog("widget").draggable({ containment: false });

      // Step 3.
      // Show the dialog
      myDialog.dialog("open");

    });
  });
  
</script>