tags:

views:

69

answers:

2

I have an object which has a property that contains an IEnumerable of objects. Each object in the IEnumerable has a property that is also an IEnumerable. I am attempting to capture a larger list of the inner property. Unfortunately, the lambda expression that I am using is returning an OrderedEnumerable. I'd like to just retrieve a simple IEnumerable.

public class OrgForm
{
    public string OrgNum { get; set; }

    public IEnumerable<CustomerForm> CustomerFormList
    {
        get
        {
            var list = from cf in OrgCustomerList
                       where cf.Customer.AssignedOrg == OrgNum
                       select cf;

            return list;
        }
    }
}

Use of CustomerFormList

OrgForm of = new OrgForm();
IEnumerable<Machine> machines = of.CustomerFormList
                                  .Select(cf => cf.ActiveMachines);

Edit

So after prompting from Jon Skeet and Mark Byers I looked a little deeper and found that ActiveMachines had been modified to perform an OrderBy so now the return of an OrderedEnumerable makes sense (my bad for not reading code set change comments).

public class CustomerForm
{
    public IEnumerable<Machine> ActiveMachines
    {
        get
        {
            var active = Customer.MachineList.ToList()
                .Where(m => "a".Equals(m.MachineStatus)
                            && !m.ToReapp);

            return active.OrderBy(m => m.MachineCategory);
        }
    }
}

This is great except machines doesn't allow me to write something like this as it sees each item in machines as an enumerable based on the category.

foreach (KeyValuePair<int, string[]> kvp in trueUpPt)
{
    Machine machine = cf.ActiveMachines
        .First(m => m.MachineSk == kvp.Key);
    machine.MachineLicenseBillback.ProjectNum = kvp.Value[0];
    machine.MachineLicenseBillback.TaskNum = kvp.Value[1];
}
+1  A: 

OrderedEnumerable<T> is an IEnumerable<T> - it's one particular implementation. Obviously you've got to return some implementation (or null) - it's not going to be an instance of the interface directly.

The code you've presented should be fine as it is. It's declared to return IEnumerable<T> so it shouldn't make any difference unless you cast the result. Having said that, the property you've shown shouldn't be returning an OrderedEnumerable anyway... Enumerable.Where just returns a new iterator. Admittedly it won't change the order so you could have an overload for Where(this IOrderedEnumerable<T>) but I don't believe there's one in the standard library.

What problem is this actually causing you, and are you using some extra libraries? If you could come up with a short but complete example it would really help.

Jon Skeet
I added my ultimate intent to the question. Thank you for the clarification on `OrderedEnumerable<T>`. Still learning lambda / linq and have to be weary of jumping to conclusions.
ahsteele
+2  A: 

If I understand "capture a larger list of the inner property" correctly, you just want

of.CustomerFormList
    .Where(cf => cf.Customer.AssignedOrg == OrgNum)
    .SelectMany(cf => cf.ActiveMachines)

That will return you an IEnumerable<Machine>. As mentioned by the other answers, IOrderedEnumerable<T> is just a subinterface of IEnumerable<T>

Isaac Cambron
+1 This looks like an intelligent guess of what he wants, based on the names of the fields. I don't see any "order by" in his code anyway so I'm still very confused about that part of his question...
Mark Byers