views:

69

answers:

2

Hello! I write a simple OLAP viewer for my web-site. Here are the classes (abstract example):

Employee
{
       ID;
       Name;
       Roles[]; //What Employee can do
}
Order
{
    Price;
    Employee Manager;
    Employee Executive; //Maybe wrong english. The person which perform order         
}

Employee can be Manager and Executive in the order at the same time. This means that Employee role is not fixed. I have to group orders by employees and finally get IGrouping with Employee key.

So .GroupBy(el=>new {el.Manager,el.Executive}) is not allowed.

I considered some tricks with IEqualityComparable, but found no solution.

If somrbody will help I'll be vary glad, thank you.

A: 

Here is a solution, with the assumption you have implemented/overridden gethashcode and equals

       var a = (
            from o in orders
            select new {
                Order = o,
                Empoyee = o.Manager
            }
            );


         var b = (
            from o in orders
            select new {
                Order = o,
                Empoyee = o.Executive
            }
            );

        var final = (a.Union(b)).Distinct().GroupBy(x=>x.Empoyee.ID, x=>x.Order);

        foreach (IGrouping<int, Order> o in final)
        {
            o.ToList();
        }
Nix
That's right cool. I think that the entity framework provider can translate this to sql and grouping will be performed by DB server. But 1) My OLAP viewer has some limitatations on creating anonymous types. Because I have many dependencies with the same set of objects. Also for simplicity, interfaces has to be as much simple as possible (this transform adds functionality). 2) I use the dynamic linq lib. I nead to test the solution with it. So a bit later I'll try this solution with my Viewer. Thank you very match.
Evgeny
you might have some trouble with pushing this down to the database. let me see if i can come up with a sql equivalent of what you want. What does your EF model look like?
Nix
A: 

To simplify architecture of the Viewer, I made transform function, which prepare data for analysis. I'll perform grouping later. This makes side effect: the sum and count of orders changes, because we produce some new orders. But in my case this is best solution, because of architecture. If I'll have troubles with DB Server, I'll invoke ToList Before this operation. I think this style is allowed by my app. Thank you one more time! :)

public IQueryable TransForDim(IQueryable E)
        {
            if (this._DimType == Измерения.Сотрудники)
            {
                if (E.ElementType == typeof(Заказ))
                {
                    var Orders = E as IQueryable<Заказ>;
                    var a = (
                    from o in Orders
                    select new
                    {
                        Order = o,
                        Empoyee = o.Менеджер
                    }
                    );

                    var b = (
                       from o in Orders
                       select new
                       {
                           Order = o,
                           Empoyee = o.Исполнитель
                       }
                       );

                    var final = (a.Union(b)).Distinct().Select(e => new Заказ()
                    {
                        Менеджер = e.Empoyee,
                        Валюта = e.Order.Валюта,
                        Выполнено = e.Order.Выполнено,
                        Дата_Выполнения = e.Order.Дата_Выполнения,
                        Дата_Поступления = e.Order.Дата_Поступления,
                        Клиент = e.Order.Клиент,
                        Отменен = e.Order.Отменен,
                        Цена = e.Order.Цена
                    });
                    return final;
                }
                else
                {
                    throw new ArgumentOutOfRangeException("Измерение не обрабатывает данные кроме заказов");
                }
            }
            else return E;
        }
Evgeny