Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can the multimapping of Petapoco handle multiple JOINs?

I have a list objects I use to fill using Petapoco.

The class properties and names are maching the database schema. The main class is Issue, and it is related to two other classes which names and properties matches the database schema too : Condition and SeverityLevel.

public class Issue
{
    public int Id { get; set; } // Primary key

    /* Some properties... */
    public DateTime? CreatedOn { get; set; }
    public string CreatedBy { get; set; }
    public DateTime? ModifiedOn { get; set; }
    public string ModifiedBy { get; set; }

    /* ... */

    // Related source and target conditions
    [PetaPoco.Ignore]
    public Condition SourceCondition { get; set; }

    [PetaPoco.Ignore]
    public Condition TargetCondition { get; set; }

    // Related severity level
    [PetaPoco.Ignore]
    public SeverityLevel CurrentSeverityLevel { get; set; }
}

public class Condition
{
    public int Id { get; set; } // Primary Key
    public string Description  { get; set; }
}

public class SeverityLevel
{
    public int Id { get; set; } // Primary key
    public string Description { get; set; }
    public string HexColorDisplay { get; set; }
}

Actually, when I retrieve a list of Issues, I am using the multimapping feature to retrieve Issue list and related SeverityLevel using a single command :

var Results = Db.Fetch<Issue, SeverityLevel, Issue>(
    (i, sl) => { 
        i.CurrentSeverityLevel = sl;
        return i;
    },
    "SELECT /* ..shortened.. */ FROM Issue " + 
    "LEFT JOIN SeverityLevel ON SeverityLevel.Id = Issue.SeverityLevelId " + 
    "WHERE Issue.Id=@0", issueId);

Now, because Petapoco does not seems to handle multiple JOINS, I need to do a second step to attach SourceCondition and TargetCondition to each Issue I retrieved.

To do so, I could either :

  • attach the Source and the Target condition after a Read, in a foreach loop,
  • or retrieve the whole list of Condition, then attach then to each Issue using the same kind of for-each.

For now, I am using the second solution because there is a limited set of Condition in the database.

Anyway, it sounds a bit heavy to me to do this way, because it requires almost as many queries to be done as JOINED tables are added.

I wonder if I could achieve to make work something like this :

var Results = Db.Fetch</* ????? */>(
    /* ???? */
    "SELECT /* ..shortened.. */ FROM Issue " + 
    "LEFT JOIN SeverityLevel ON SeverityLevel.Id = Issue.SeverityLevelId " + 
    "LEFT JOIN Condition Con1 ON Con1.Id = Issue.SourceConditionId " + 
    "LEFT JOIN Condition Con2 ON Con2.Id = Issue.TargetConditionId " + 
    "WHERE Issue.Id=@0", issueId);

Dear Petapoco users, dear Petapoco author, is this a way to handle this ?

Could I use Dapper to deals with this instead (if it can...), appart I absolutely want to keep Petapoco for my update/insert operations ?

like image 894
Larry Avatar asked Jul 12 '11 12:07

Larry


1 Answers

This should be able to be done.

var Results = Db.Fetch<Issue, SeverityLevel, Condition, Condition, Issue>(
    (i, sl, c1, c2) => { 
        i.CurrentSeverityLevel = sl;
        i.SourceCondition = c1;
        i.TargetCondition = c2;
        return i;
    },
    "SELECT Issue.*, SeverityLevel.*, Con1.*, Con2.* FROM Issue " + 
    "LEFT JOIN SeverityLevel ON SeverityLevel.Id = Issue.SeverityLevelId " + 
    "LEFT JOIN Condition Con1 ON Con1.Id = Issue.SourceConditionId " + 
    "LEFT JOIN Condition Con2 ON Con2.Id = Issue.TargetConditionId " + 
    "WHERE Issue.Id=@0", issueId);

I have not tested this. I am also working on a way to automate this.

It's really important that the columns selected are in the same order that the parameter types are.

like image 188
Schotime Avatar answered Oct 02 '22 18:10

Schotime