Return the same type for two views from datacontext

63 Views Asked by At

I have created two views that return exactly the same columns from the same tables. The only difference between the two views is they filter on different parameters. I have added these into my .dbml file (Picture of views in dbml) This has then auto generated two classes for these two views.

In my code depending on the value of the property Filter one of the two views is queried, either current or previous. I need these views to be returned as the same type. So that IOrderedQueryable<> items has one return type.

Currently they are returning as either clientOrdersQueryCurrent or clientOrdersQueryPrevious. If I set IOrderedQueryable<> items to either one of these and attempt to cast the other type then this causes a runtime error.

        IOrderedQueryable<> items;
        bool filterQuery = false;
        if (!string.IsNullOrEmpty(OrderNumber) || DateFrom != null || Dateto != null || !string.IsNullOrEmpty(TrackingNumber) || UserId != null)
        {
            filterQuery = true;
        }

        if (Filter == "Current")
        {
            if (filterQuery)
            {
                items = dataContext.clientOrdersQueryCurrents.Where(o => o.client_id == currentClientIdProvider.GetCurrentClientId()
                            && (string.IsNullOrEmpty(OrderNumber) || o.OrderNumber.Contains(OrderNumber))
                            && (DateFrom == null || o.OrderPlaced >= DateFrom)
                            && (Dateto == null || o.OrderPlaced <= Dateto)
                            && (string.IsNullOrEmpty(TrackingNumber) || o.TrackingReference.Contains(TrackingNumber))
                            && (UserId == null || o.UserId == UserId)).OrderByDescending(o => o.OrderPlaced);
            }
            else
            {
                items = dataContext.clientOrdersQueryCurrents.Where(o => o.client_id == currentClientIdProvider.GetCurrentClientId()).OrderByDescending(o => o.OrderPlaced);
            }
        }
        else if (Filter == "Previous")
        {
            if (filterQuery)
            {
                items = dataContext.clientOrdersQueryPrevious.Where(o => o.client_id == currentClientIdProvider.GetCurrentClientId()
                            && (string.IsNullOrEmpty(OrderNumber) || o.OrderNumber.Contains(OrderNumber))
                            && (DateFrom == null || o.OrderPlaced >= DateFrom)
                            && (Dateto == null || o.OrderPlaced <= Dateto)
                            && (string.IsNullOrEmpty(TrackingNumber) || o.TrackingReference.Contains(TrackingNumber))
                            && (UserId == null || o.UserId == UserId)).OrderByDescending(o => o.OrderPlaced);
            }
            else
            {
                items = dataContext.clientOrdersQueryPrevious.Where(o => o.client_id == currentClientIdProvider.GetCurrentClientId()).OrderByDescending(o => o.OrderPlaced);
            }
        }
        else 
        {
            //Default call - current orders
            items = dataContext.clientOrdersQueryCurrents.Where(o => o.client_id == currentClientIdProvider.GetCurrentClientId()).OrderByDescending(o => o.OrderPlaced);
        }

The only thing I can currently think of to resolve this is to create a class and have the query map the result to the class after it returns.

What is the best way to do this?

The ORM I am currently using is NHibernate.

1

There are 1 best solutions below

0
On

Better to map to some common class

IOrderedQueryable<CommonItem> items;

items = dataContext.clientOrdersQueryCurrents.Select(e => new CommonItem{...});
...
items = dataContext.clientOrdersQueryPrevious.Select(e => new CommonItem{...});

It can be AutoMapper's ProjectTo method

items = dataContext.clientOrdersQueryPrevious.ProjectTo<CommonItem>();