Relationships in XPO

I’m replying to a post in the DevExpress XPO forum, where the question came up of how to use joins with XPO/LINQ and projection. Unfortunately, the forum system mangled my code snippets, so I thought I’d put the info up here as well.


Emilio Garcia wrote:

I trying to create a linq query to retrive some objects, this is the query:

var
listadoSesiones = from u in usuariosjoin s in sesiones on u.ObjId equals
s.UsuarioIdwhere s.Activa == true
orderby s.FechaInicio ascending
select new { u.NombreUsuario, u.NombreCompleto, s.FechaInicio, s.FechaFin };

I’m pretty sure this doesn’t have anything to do with the Guid type.
Instead, the problem is the projection you’re trying to do. Instead, you
should define your classes correctly and things should be much easier…

I’m roughly translating your names, and I’m coming up with classes that
look like this:


public class User: XPObject {
  public User(Session session) : base(session) { }

  private string userName;
  public string UserName {
    get { return userName; }
    set { SetPropertyValue("UserName", ref userName, value); }
  }

  private string fullName;
  public string FullName {
    get { return fullName; }
    set { SetPropertyValue("FullName", ref fullName, value); }
  }

  [Association("User-Sessions")]
  public XPCollection Sessions {
    get { return GetCollection("Sessions"); }
  }
}

public class LoginSession: XPObject {
  public LoginSession(Session session) : base(session) { }

  private DateTime startTime;
  public DateTime StartTime {
    get { return startTime; }
    set { SetPropertyValue("StartTime", ref startTime, value); }
  }

  private DateTime endTime;
  public DateTime EndTime {
    get { return endTime; }
    set { SetPropertyValue("EndTime", ref endTime, value); }
  }

  private bool active;
  public bool Active {
    get { return active; }
    set { SetPropertyValue("Active", ref active, value); }
  }

  private User user;
  [Association("User-Sessions")]
  public User User {
    get { return user; }
    set { SetPropertyValue("User", ref user, value); }
  }
}

Note the two properties marked with [Association] – these are the ones
that implement the relationship for XPO. You should always set these
relationships up correctly, then it will be much easier to get to the
right data.

(As an aside – when working with legacy databases, you’ll sometimes need
to use the [Persistent(...)] attribute on properties like this to define
the name of the foreign key fields in your database.)

Once you’ve got your classes set up like this, you can easily query the
information you were looking for, utilizing these pre-configured
relationships:


using (UnitOfWork unitOfWork = new UnitOfWork( )) {
  var activeSessions =
    from s in new XPQuery<LoginSession>(unitOfWork)
    where s.Active
    orderby s.StartTime
    select new {
      s.User.UserName,
      s.User.FullName,
      s.StartTime,
      s.EndTime // why this? session is active, no end time...
    };
  foreach (var session in activeSessions)
    Console.WriteLine("Username: {0}, Full name: {1}, Start time: {2}",
      session.UserName, session.FullName, session.StartTime);
}

Of course on the other hand there’s no real need to do this either –
it’s so easy to get to the data you need through the relationship
properties, you don’t need to work with projection.

3 Comments on Relationships in XPO

  1. Very helpful, especially the example code!

    Like

  2. Hi Joe,

    Thanks 🙂

    I just found that there were still things wrong with the code (the XPQuery wasn’t initialized correctly), due to my own code highlighting thing… now I fixed it and it should look nicer and also be correct.

    Like

  3. Emilio Garcia Granda // June 25, 2010 at 8:15 pm // Reply

    Thanks was very helpful example!

    Like

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s