Thursday, December 11, 2014

Entity-ORM Hybrid

Sometimes you end up working on a project that shifts away from Entity Framework in favor of something else, ADO.NET, Linq to Sql, an available ORM, or maybe even a homegrown ORM.  That's what happened at one client I've worked with.  There were a few reasons to move away from EF, mostly based on misunderstandings, database design, and lack of knowledge of the product.  But there are still some things EF does better than some other methods.  Instead of writing a new stored procedure in SQL Server every time we need to update one field, we set out to use the features of EF to make that happen a little more easily.  After all, isn't it better when you can pass two variables to your repository and just wait for the true/false response?  That's right, it is better.

Here's the code:

   1:  public bool Save<T>(T domainModel, string idFieldName) where T : class
   2:          {
   3:              var type = typeof(T);
   4:              var idProperty = type.GetProperty(idFieldName);
   5:              var domainModelIdValue = (int)idProperty.GetValue(domainModel, null);
   6:   
   7:              var match =
   8:                  Context.Set<T>().Where(PropertyEquals<T, int>(idProperty, domainModelIdValue)).ToList();
   9:   
  10:              // if there's more than one record with a matching ID field (which shouldn't be possible as long as our field is specified correctly) we can't do this update
  11:              // also, if there's no match from the database on the ID field, we can't do this update
  12:              if (!match.Any() || match.Count() > 1)
  13:              {
  14:                  return false;
  15:              }
  16:   
  17:              var firstMatch = match.First();
  18:   
  19:              // set all properties from the domain model passed to the match found in the database
  20:              Context.Entry(firstMatch).CurrentValues.SetValues(domainModel);
  21:   
  22:              var numberOfObjectsWrittenToUnderlyingDatabase = Context.SaveChanges();
  23:   
  24:              return numberOfObjectsWrittenToUnderlyingDatabase == 1;
  25:          }
  26:   
  27:          public Expression<Func<TItem, bool>> PropertyEquals<TItem, TValue>(PropertyInfo property, TValue value)
  28:          {
  29:              var param = Expression.Parameter(typeof(TItem));
  30:              var expressionProperty = Expression.Property(param, property);
  31:   
  32:              BinaryExpression body;
  33:              if (Nullable.GetUnderlyingType(expressionProperty.Type) != null)
  34:              {
  35:                  var comparisonValue = Expression.Convert(Expression.Constant(value), typeof(int?));
  36:                  body = Expression.Equal(expressionProperty, comparisonValue);
  37:              }
  38:              else
  39:              {
  40:                  body = Expression.Equal(Expression.Property(param, property), Expression.Constant(value));
  41:              }
  42:   
  43:              return Expression.Lambda<Func<TItem, bool>>(body, param);
  44:          }

Tuesday, December 2, 2014

Angular ng-include

If you need to bring one HTML file into another using Angular, you may want to take advantage of the ng-include directive (documentation can be found here).  Using ng-include will bring in the specified HTML file.

<div ng-include="'/Pages/SomeApp/Ordering.html'">

Be careful, though!  I ran into a problem with this directive that was driving me crazy.  I had used ng-include in a file that also had an ng-include in it and it caused me no small headache.  Others have done the nested ng-include so it may have just been my specific usage that was causing problems, but it's worth noting.

In case you're seeing something similar, I was forced to use IE 8 (you can peruse my hatred of that browser in other posts) and whenever the ng-hide class was applied, the entire screen went blank.  The DOM was technically still there, but you couldn't see anything.  Good times.  Or not.

Plain HTML as a Partial View

Sometimes you just need to include a plain HTML file in another MVC view.  It's easy enough.  Just use the code below and you should be all set.

@Html.Raw(File.ReadAllText(Server.MapPath("~/Pages/SomeApp/Ordering.html")))

Friday, November 7, 2014

Scope Objects in the Console

When you need to quickly print a scope value in the console (I use Chrome), you can use this helpful little guy:

angular.element("#elementId").scope()

Just a little bit of code that can help immensely.

Friday, October 10, 2014

Stayin' Alive

It's been a while since I posted.  I'm not sorry.  Life is busy.  You'll just have to learn to deal with missing me.  That's how our love works.

I recently had to figure out how to keep my .NET application "alive" or "awake" between requests.  This particular site belongs to a small business that is just getting started.  Since they're not sure how big their site might get we decided to stay small and use shared hosting from GoDaddy.  One of the problems they were encountering was that the site was always so "slow".  I couldn't figure out what they were talking about for quite some time until I finally hit the page early one morning, before anyone else had hit it for the day.  It was slow.  Obnoxiously slow.

IIS was recycling the app pools when no one visited the page for a period of time.  What I needed was a solution to make that stop happening.  I found a clever little solution that works for us, but has some obvious pitfalls.  H/t to Omar Al Zabir at Codeproject for this one.  If you actually clicked that link and read the original solution you may have noticed that it's quite old.  But who cares?  It works.

Basically, you create a cache item with a callback.  When the cache item expires and the callback fires, the callback hits your site.  I modified the solution a little bit to do what I needed.  I have a separate service from my website so I wanted to keep both of them alive.  Easy.  Check it out.

This is from the global.asax.cs from the web project:


That's pretty much the whole shebang right there.  Actually, that's not "pretty much" it.  That's it.  There are obviously some web.config values to add, but I think you can figure that out.

Tuesday, September 23, 2014

Angular JS ajaxComplete

I recently came across a problem where our ajaxComplete function wasn't being executed from jQuery after we started using Angular.  As it turns out (it was a bit of a "duh" moment) the issue was that when using Angular we were no longer using the jQuery ajax calls.  So the jQuery ajaxComplete function was never fired because no jQuery ajax calls were ever made.

That set me on a path of trying to figure out how to mimic the ajaxComplete behavior with Angular and this is what I came up with.  I haven't fully tested it, but wanted to put it up here before I forget so I can have a better starting point next time this comes up.

After the application has been created, configure the $httpProvider to have an intercept:

angularApp.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.interceptors.push(function ($q) {
        return {
            response: function (response) {
                return response;
            }
        };
    });
}
]);

This particular implementation won't do anything but act as a pass through, but it can be modified however necessary to meet your needs.

Monday, August 11, 2014

Getting Distinct from a List

Sometimes you have a list of complex objects that you need to pare down to be a list of distinct complex objects.  LINQ offers a way to do that, but unless you've done it before it's not immediately obvious as to what you need to do.  There are two ways to do it, and they're actually pretty easy to implement.

If the complex object is your own creation, just implement IEquatable where T is the type of the object.  Something like this:



Once you've implemented IEquatable on your class, you just have to invoke the .Distinct() call on your list.  Here you go:



Here are the results of the IEquatable approach:


If you find yourself in a situation where the complex object can't be extended to implement IEquatable, there's a solution for that, too.  You'll create an additional class that implements IEqualityComparer and then specify that when you invoke the .Distinct() call on your list.







Here are the results of using the IEqualityComparer approach: