Skip to content

Tuples In C#, A Useful Example

Updated: at 02:12 PM

Background

Last year I worked consulted with a company that had an engineer that used tuples in C# and tried to explain to me how they were useful.  To be honest, I never quite saw the value proposition (until today).  I remember he kept saying they were kind of like key value pairs but could go beyond that.  I remember those words but never internalized that.

The Example

My example is a simple one.  I’m currently working on providing data to an external application that will provide business intelligence (help with session selection) to the Silicon Valley Code Camp web site.  The data I’m providing is every mark of interest and plan to attend for every session ever given at code camp (that’s 220,000 records).  I also want to add to those records the session evaluation results for those people.  For example, one of those 220,000 records looks like this:

public class SessionAttendeeRec
{
    public string Id { get; set; } // because ST sends up strings on new records
    public int AttendeeId { get; set; }
    public int SessionId { get; set; }
    public bool Interested { get; set; }
    public bool WillAttend { get; set; }
    public DateTime LastUpdatedDate { get; set; }
    public int HoveredOverCount { get; set; }
    public bool EvalDone { get; set; }
    public int EvalCourseAsWhole { get; set; }
    public int EvalOverallCodeCamp { get; set; }
}

I can get most of this data from one table (SessionAttendee) which is defined as follows:

CREATE TABLE [dbo].[SessionAttendee] (
  [Id] int IDENTITY(1, 1) NOT NULL,
  [SessionsId] int NOT NULL,
  [AttendeesId] intNOT NULL,
  [Interestlevel] int NOT NULL,
  [LastUpdatedDate] datetime NULL,
  [UpdateByProgram] nvarchar(64) NULL,
  [Cnt] int NULL,
  [SignupDate] datetime NULL,
  [SignUpCancelByDate] datetime NULL,
  [PayDate] datetime NULL,
  [PayAmount] decimal(19, 4) NULL,
  [PayComment] varchar(1024)  NULL,
  [Note] varchar(1024)  NULL,
  [ChargeAmount] decimal(19, 4) NULL,
  PRIMARY KEY CLUSTERED ([Id])
)

However, I have two extra fields (EvalCourseAsWhole and EvalOverallCodeCamp) I need to fill in from another table (SessionEvals).

CREATE TABLE [dbo].[SessionEvals] (
  [Id] int IDENTITY(1, 1) NOT NULL,
  [SessionId] int NOT NULL,
  [AttendeeId] int NOT NULL,
  [CourseAsWhole] int NULL,
  [OverallCodeCamp] int NULL,
  PRIMARY KEY CLUSTERED ([Id])
)

I could use an outer join for this but in this case I chose to do two selects, one of the first table in it’s entirety

// create the dictionary that will hold the tuples
var sessionEvals = SessionEvalsManager.I.GetAll();
dict = new Dictionary<Tuple<int, int>, SessionEvalsResult>();
foreach (var s in sessionEvals)
{
    var tuple = new Tuple<int,int>(s.sessionId,s.attendeeId);
    dict.Add(tuple, s);
}
foreach (var r in sessionAttendeeRecs)
{
        var tuple = new Tuple<int, int>(r.sessionId, r.attendeeId);
        if (dict.ContainsKey(tuple))
        {
            var sessionEval = dict[tuple];
            r.EvalCourseAsWhole = sessionEval.CourseAsWhole ?? -1;
            r.EvalOverallCodeCamp = sessionEval.OverallCodeCamp ?? -1;
            r.EvalDone = true;
        }
}

Check out the ORM (Object Relational Mapper) PRISMA. The database access method I use in all my projects