www.allpaul.com

I needed somewhere to put all this crap
Welcome to www.allpaul.com Sign in | Help
in Search

Programming

  • Entity Framework Stored Procedure Gotcha

    I recently discovered and interesting tidbit about stored procedures and their counterparts, function imports, in the entity framework (EF).  In the past I have used stored procedures in the EF when I need to do complex operations when adding new database records. The one thing I never really paid attention to was the return type of the stored procedure.  I'll generally add a select * from the  corresponding table and return all the values of the newly added row.  Then in the EF model designer, I create a function import and set the return type to the type of object just added. 

    I needed to return a scalar value (int) from a stored procedure and that's where the gotcha comes in.

    It seems that the object context (OC) of an EF model doesn't handle scalar return types.  The model designer allows you to create the function import and set the return type to a scalar value, however the model will not have any reference to the new method (via intellisense or at runtime).

    I found a few posts discussing the issue which seems to be fixed in the next version of the EF...Here are a few links

    http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/4fae55c8-e103-46a8-b4c3-16077e912bf9

    http://www.danrigsby.com/blog/index.php/2009/05/20/entity-framework-40-scalar-and-void-functions/

    For now I am going to use the method in the first link.  I'll create a function that encapsulate some database code and replace it later when the next version of the EF is out.

  • Linq to entities "IN" query

    Recently I was looking for a way to build the following SQL query using the entity framework 

       1:  SELECT * FROM tbl_Registrations WHERE [ID] IN (1, 2, 3, 4, 5)
    
    

    But, turns out, that is not very easy. I thought of three different approaches. To begin, I have a entity set Registrations of entities Registration.  These Registration entities have a property ID (int).  So I tried,

    1. Create an int array of the IDs and use the Intersect operator.  But, and there may be other reasons, the Intersect operator doesn't accept Lambda expressions and without it the result would only be a list of ints, which I already had.

    2. Create an int array (Or List<int> or List<MyTypeWithIntProperty>) then join the array/list to my Registrations on the ID equal to the value in the array or list.  That doesn't work.

    3. Use the Any operator with the same list/array from #2 with a Lambda expression.  That didn't work either.

    Normally, I would then just hit the newsgroup and do a search, but I couldn't search on the word IN and the word Any yielded more than 2000 results. After plugging through the almost random search results I finally came across another gem from Colin Meek. The post shows how to achieve the desired results using a utility method to construct an expression of concatenated or statements.  So, my original query gets translated into

          (r.ID == 1 || r.ID == 2 || r.ID == 3 ...)

    To clarify HOW to implement his example, I did the following

       1:  int[] regIds = { 1, 2 };
       2:   
       3:  var regs = (from r in se.Registrations
       4:                          select r)
       5:             .Where(Extensions.
       6:             BuildContainsExpression<Registration, int>(e => e.ID, regIds));

     

    It should be noted that I have a class that contains all my extension and helper methods called Extensions. Hopefully, by me writing about this it will help anyone looking for way to implement a "IN" query in Linq to entities.

    Good luck

     

  • Deriving entities from a common interface

    My current project has this concept of Activities.  Activities are defined as anything we want to track for a particular Company or Contact in the database.  A typical Activity may be

    ID = 21

    Description = Contacted office

    IsCompanyOnly = false

    Now, as I said a company or contact may have these activities added so there are two tables in the database to facilitate this...tbl_Company_Activities and tbl_Contact_Activities...But for this discussion we don't care about the tables as much as the Entities generated from them.

    Here is a diagram of how this is all shakes out (there is more than just this activity scenario going on in this diagram, so just focus on the Activity, CompanyActivity and ContactActivity entities):

     

    You see how they are exactly the same except their type CompanyActivity vs ContactActivity and the reference to either a Company or Contact?  All of the other fields are the same...And it just so happens that I need to get a list of all company and contact activities for a given company...I smelled an interface. I am going to extract the common fields Notes, ActivityDate, User, and ActivityCode and then add readonly (get properties) for the Type and RecordID (company or contact ID). here is that interface 

       1:  using System;
       2:  using MyModel;
       3:   
       4:  public interface IActivityRecord
       5:  {
       6:      string Notes
       7:      {
       8:          get;
       9:          set;
      10:      }
      11:   
      12:      DateTime ActivityDate
      13:      {
      14:          get;
      15:          set;
      16:      }
      17:   
      18:      DbUser User
      19:      {
      20:          get;
      21:          set;
      22:      }
      23:   
      24:      RecordInfoType RecordType
      25:      {
      26:          get;
      27:      }
      28:   
      29:      int RecordId
      30:      {
      31:          get;
      32:      }
      33:   
      34:      Activity ActivityCode
      35:      {
      36:          get;
      37:          set;
      38:      }
      39:  }
    
    
    
    

    Okay so now I need to implement this interface.  Remember that my model already defined CompanyActivity and Contact as containing  Notes, ActivityDate, User, and ActivityCode, so the only implementations that are up to me are the RecordType and RecordId.  It should be said at this point that RecordType is of type RecordInfoType which is an Enum that contains Company and Contact.  It should aslo be said that this next example code snippet builds upon my previous example Adding computed properties to Entity Framework Entities which shows you how to extend model-generated entities through partial classes.

       1:  using System.Linq;
       2:   
       3:  namespace MyModel
       4:  {
       5:      public partial class ContactActivity : IActivityRecord
       6:      {
       7:   
       8:          public RecordInfoType RecordType
       9:          {
      10:              get { 
      11:                  return RecordInfoType.Contact; }
      12:              
      13:          }
      14:   
      15:          public int RecordId
      16:          {
      17:              get
      18:              {
      19:                  int ret = 0;
      20:                  if (this.ContactReference.IsLoaded)
      21:                      ret = this.Contact.ID;
      22:                  else
      23:                  {
      24:                      using (MyEntities se = new MyEntities())
      25:                      {
      26:                          ret = (from a in se.ContactActivities where a.ID == 
                                           this.ID select a.Contact.ID).FirstOrDefault();
      27:                      }
      28:                  }
      29:                  return ret;
      30:              }
      31:          }
      32:      }
      33:  }

     That was the ContactActivity now here is the CompanyActivity:

       1:  using System.Linq;
       2:   
       3:  namespace MyModel
       4:  {
       5:      public partial class CompanyActivity : IActivityRecord
       6:      {
       7:   
       8:          public RecordInfoType RecordType
       9:          {
      10:              get { return RecordInfoType.Company; }
      11:          }
      12:   
      13:          public int RecordId
      14:          {
      15:              get
      16:              {
      17:                  int ret = 0;
      18:                  if (this.CompanyReference.IsLoaded)
      19:                      ret = this.Company.ID;
      20:                  else
      21:                  {
      22:                      using (MyEntities se = new MyEntities())
      23:                      {
      24:                          ret = (from a in se.CompanyActivities 
                                        where a.ID == this.ID select a.Company.ID).FirstOrDefault();
      25:                      }
      26:                  }
      27:                  return ret;
      28:              }
      29:          }
      30:      }
      31:  }

    Cool, huh? Now I can bind a

    IEnumerable<IActivityRecord>

    to a GridView or work with it as a collection by retrieving it using linq...Oh, wait, I'll still need to downcast, here is a method that takes a Company object and returns a IList<IActivityRecord> of all the activities for the company and all its contacts:

     

       1:   public IList<IActivityRecord> getAllActivities(Company _company)
       2:      {
       3:          IList<IActivityRecord> ret = null;
       4:          using (MyEntities se = new MyEntities())
       5:          {
       6:              IEnumerable<CompanyActivity> companyactivities =
       7:                  (from ca in se.CompanyActivities
                         .Include("Company").Include("ActivityCode").Include("User")
       8:                   where ca.Company.ID == _company.ID
       9:                   select ca);
      10:   
      11:              ret = companyactivities.ToList()
      12:                  .ConvertAll(obj => obj as IActivityRecord);
      13:   
      14:              IEnumerable<ContactActivity> contactactivities =
      15:                  (from ca in se.ContactActivities
                            .Include("Contact").Include("ActivityCode").Include("User")
      16:                   where ca.Contact.Company.ID == _company.ID
      17:                   select ca);
      18:   
      19:              ret.Union(contactactivities.ToList()
      20:                  .ConvertAll(obj => obj as IActivityRecord));
      21:          }
      22:          return ret;
      23:      }

     

    Now there would need to be some logic on the consumer side to use the collection in other ways than just straightfroward databinding, but the RecordType and RecordID properties should allow the consumer to do what ever operations they need to.

    Good luck.

     

  • Adding computed properties to Entity Framework Entities

    I have been working on a project using the Entity Framework.  One of the many cool features of the framework is it generates entity classes as partial classes so you, or in this case I, can extend an entity to include computed properties or methods.

    In this example I have a Contact entity.  It has many properties including, FirstName, MiddleInitial and LastName.  I'd like to be able to access a property called FullName so I don't have to jump through all kinds of string null value checks and concatenation every time I need to display the contact's name. So, here is my entity Contact from the Entity Designer

    Contact Entity

    I can add to the partial class to include the property by creating a new class file (Contact.cs) and adding the correct namespace and including the partial keyword...Like this 

    namespace DBModel 
    { 
    
        public partial class Contact 
        { 
            public string FullName 
            { 
                get 
                { 
                    string ret = string.Empty; 
                    if (!String.IsNullOrEmpty(FirstName)) 
                        ret += FirstName; 
                    if (!String.IsNullOrEmpty(MiddleInitial)) 
                        ret += " " + MiddleInitial; 
                    if (!String.IsNullOrEmpty(LastName)) 
                        ret += " " + LastName; 
                    return ret; 
                } 
            } 
        } 
    
    }

    Now every time I need the contact's name I can just do a

         myContact.FullName

    Sweet!

  • Entity Framework Designer Problems (VS-SP1 Beta release)

    I have been developing a site using the latest release of the Entity Framework (EF).  The EF is great because it allows me to create business objects that are not directly related to database tables without too much code.  These new objects can be completely different in structure from the relational database that persists them.  For example...I have a Company object that has various attributes like Name, Phone, Fax, Web site and Addresses.  That Addresses is a collection of Address objects from a different database table.  But, I needn't worry about that once I design how I want to present my objects in the Entity Model Designer (More on that in a minute).  Back to that address thing. 

    The Company - Address relationship is more complex than CompanyID being a field in the Address table.  Instead, because Companies can share an Address (two companies are at the same location or have the same billing address and when it is updated for one company it will automatically update for the other) there is actually a many-to-many relationship here with a joining table in the database.  That relationship looks like this:

    Company->CompanyID, Name, ...

    Address->AddressID, Street1, Street2, City, ...

    CompanyAddress->CompanyID, AddressID

    The one of the coolest things about the EF is once I set up that relationship in the designer (it does most of the work for you really), I can use my objects in a more traditional Conceptual and not Relational way.

    So, I can load my Company object and its Address objects using Linq  (overly simplified in this example)

            
            Company c = (from comp in context.Companies select comp).First();
    
            c.Addresses.Load();
    
            foreach (Address a in c.Addresses)
                Console.WriteLine(a.Street1);
    

    Cool! But, I have had some troubles with the designer that I believe are just due to its infancy as a product.

    1. The designer creates a .edmx file that stores all of the relations, renamings and reorganization of your database - conceptual model structure. It also creates a ModelName.designer.cs file that includes the generated classes for your new conceptual objects.  This .designer.cs file is created automatically when you build (or save, I think) the .edmx file.  However, on three occasions in two weeks this linking between the files has been lost.  I think it has to do with me restoring the files from backups or moving the directory where the .edmx file lives.  I plan to troubleshoot it more next time it happens.
    2. If you delete a conceptual object that is generated from a database table, there is no easy way to regenerate that class.  I would think right-clicking on the table name in the Model Browser would have some functionality like that, but it only allows an "Update from database" that doesn't recreate the deleted object (and I think that is right because if it did and you really wanted it deleted, you'd be pissed every time it came back).
    3. If you forget to add a relation to your database before generating your Model, go back and add the relationship and then update from database to refresh the Model with the new information, it often becomes difficult to get the table mapping correct.

    I think the tool is great in 80% of the scenarios I've thrown at it, but it needs a bit more work.  And, the development team should put together a Webcast to demonstrate how to use the designer for more difficult scenarios.  The only ones covered so far are very simple.

     

  • Article picked up by Microsoft's ASP.NET Web site

    An article I wrote was picked up to run on one of Microsoft's Developer Web sites--www.asp.net. The article has since fallen off the front page. But, luckily, I have archived a screenshot for your enjoyment.

    In the ASP.NET Articles section, the one listed with a red Today! is mine.

    Click here for a screenshot

  • School Projects

    This is a collection of some (not all) of the programs I have written for school. There isn't much in the way of descriptions yet, but I plan to add those later. Right now it's just the raw files although they are commented.

    To view the files, click here

  • Creating a Banner Ad System in ASP.NET

     In this article I build a banner ad display system using ASP.NET and SQL Server 2000. The system's features include :

    • An html form-based administration for non-techies.

    • An advertisement weighting option.

    • Click tracking.

    Published on 4guysfromrolla.com March 31, 2004.

  • TV Audio Recorder

     This program began as a way to record the audio from 60 Minutes (I know I could do it from the radio too...In fact I have built a similar program for radio broadcasts like CarTalk) so I could copy it to my mp3 player and listen to it in the car on road trips.

    The program is a work in progress and I owe a lot to many others who have contributed (unknowingly) by posting various tutorials online.

    As the program lives today, you can control Sony Directv recievers only. I plan to make it possible to control RCA recievers, but the one I ordered for testing purposes has not arrived yet.

    Requires the .NET Framework.

    Read the help for more information.

    Click here to download the program

    (ALL of this was before podcasts)

  • LAME mp3 converter front end

    This application is a front end for LAME (a command line mp3 encoder). It allows users to browse to a .wav file, convert it, and optionally delete it.

    mp3converter.zip

    This program includes the source code written in Visual Basic.NET.

  • Building an Event Calendar Web Application

    This article examines how to build an event calendar Web application that allows users to enter information for specific events into a database. This information is then displayed using the ASP.NET Calendar Web control so that users can see an overview of the month's activities.

    Published on 4guysfromrolla.com April 16, 2003.

  • Web-enabled caller id -- part three

    In part one I built a VB6 program to monitor my telephone and update a SQL Server database with incoming caller id information. Part 2 focused on building a Web service that exposes methods for reading and manipulating the caller id data. In this part...
  • Web-enabled caller id (part 1)

    In this series of articles I will demonstrate build an application that will save incoming caller id information to a SQL Server database. Then, I will build a Web service that exposes methods for reading and deleting the information. And, finally, I'll...
  • Web-enabled caller id -- part two

    In part 1 I built a VB6 program to insert incoming caller id information into an SQL server database. In order to have the information available online, I'm going to have to write some kind of Web page to retrieve the data from the database. I could...
Powered by Community Server (Non-Commercial Edition), by Telligent Systems