Replace QuerySourceReference by another mapped entities

10 views
Skip to first unread message

Jordi Cabré

unread,
Jun 7, 2016, 4:49:39 AM6/7/16
to re-motion Users
I'm building an application which's backend agnostic. In order to get it, I've create an interface IBackend looks like:

    public interface IBackend
   
{
       
IQueryable<Backend.Domain.FollowUpActivity> FollowUpActivities { get; }
       
IQueryable<Backend.Domain.Resource> Resources { get; }
        //...
        IQueryable<T> Query<T>();
   
}

Currently, I've created two implementations: Server (generates sentences to our server...) and memory (it's not a very advanced implementation). Server is using re-linq in order to generate sentences and works fine.
Nevertheless,
we intended to build the memory backend based on the default Linq Collections Provider. We have suddently come up with a trouble: the connection with UI Domain Entities and Backend Domain Entities.
So, along with
IBackend interface we provide a sort of classes that draw an optional domain users can take in order to build their UI clients. So, Memory Backend is using these entity classes in order to create several List<Entity>:

        private List<Domain.FollowUpActivity> followUpActivities;
       
private List<Domain.Resource> resources;
        //...

By now, IBackend's MemoryBackend  implementation looks like:

        public override IQueryable<FollowUpActivity> FollowUpActivities
       
{
           
get
           
{
               
return this.followUpActivities.AsQueryable();
           
}
       
}

       
public override IQueryable<Resource> Resources
       
{
           
get
           
{
               
return this.resources.AsQueryable();
           
}
       
}

       
//...

       
public override IQueryable<T> Query<T>()
       
{
           
//????????????????????
       
}

As you can see, we're using AsQueryable() method in order to get straightforwardly the default .Net Linq Collection Provider.
So, we've to provide an implementation for IQueryable<T> Query<T>() method. However, T can be whichever entity class developer have created in his/her development. So, I'm not able to provide something like collection.AsQueryable(), since Memory backend implementation doesn't have this collection<T>.

Idea:

We have running on the idea of building a Linq provider using Re-linq in order to be able to replace whichever entity reference by its related Domain entity, pick up its related collection of <T> and perform Linq sentence over this collection.
We've several mechanisms let us figure out which is the relationship between any external entity class with our Domain entity classes. The easiest way is using a "by convention attribute" setting up the entity class is a Domain entity class:

UI Class:
    [Backend.Infrastructure.Attributes.FollowUpActivity]
   
public class BOFollowUpActivity
   
{
        private string id;              // Generated on server
       
private DateTime? creationDate;
       
//...

       
public String Id { //... }
       
public DateTime? CreationDate { //... }
       
//....

Domain Class:   
    public class FollowUpActivity
   
{
       
private string id;              // Generated on server
       
private DateTime? creationDate;
       
//...

       
public String Id { //... }
       
public DateTime? CreationDate { //... }
       
//....

With this information (attribute), we're able to get that BODomain.BOFollowUpActivity is a by-convention class of Domain.FollowUpActivity. "By conventions" means they have the same properties.
So, as far we are able to get our backend domain class, we are able to replace linq sentence references by its related backend domain classes, and perform it on backend's collections.

We've tried to create a Expression visitor and visit each QuerySourceReference and replace its Type property by another one, however, we are not able to figure out how to replace each querysourcereference safely.

Any ideas?
It's a good approach?
Do you have another proposals?
Reply all
Reply to author
Forward
0 new messages