user482375
user482375

Reputation:

ForEach over Object error

I have a query in a method so I can call i from multiple places like so:

private object GetData(ProfilePropertyDefinition lProfileProperty)
{   
    return from r in gServiceContext.CreateQuery("opportunity")
           join c in gServiceContext.CreateQuery("contact") on ((EntityReference)r["new_contact"]).Id equals c["contactid"] into opp
           from o in opp.DefaultIfEmpty()
           where ((EntityReference)r["new_channelpartner"]).Id.Equals(lProfileProperty.PropertyValue) && ((OptionSetValue)r["new_leadstatus"]).Equals("100000002")
           select new
           {
               OpportunityId = !r.Contains("opportunityid") ? string.Empty : r["opportunityid"],
               CustomerId = !r.Contains("customerid") ? string.Empty : ((EntityReference)r["customerid"]).Name,
               Priority = !r.Contains("opportunityratingcode") ? string.Empty : r.FormattedValues["opportunityratingcode"],
               ContactName = !r.Contains("new_contact") ? string.Empty : ((EntityReference)r["new_contact"]).Name,
           };
}

Then in another method I call the query method like so and try to loop through it:

var exportData = GetData(lProfileProperty);
foreach (var lItem in exportData)
{
}

Then in the same method when I try to loop through the results I keep getting this error on the foreach:

foreach statement cannot operate on variables of type 'object' because 'object' does not contain a public definition for 'GetEnumerator'

Any idea what would cause and how to fix it, I'm stumped.

EDIT:

Took Jon's advice and for the most part it seems to be working. But when I call the method like: GetData<lProfileProperty.PropertyValue>; It says lProfileProperty can't be found. But it's there. Any ideas?

EDIT 2: I have everything from Jon's example in place. I'm getting one error though: On foreach (GridDataItem lItem in exportData) it is saying Error 67 Cannot convert type 'DotNetNuke.Modules.CPCLeadShare.View.Foo' to 'Telerik.Web.UI.GridDataItem' any ideas on how to fix this? I need to be able to use the DGridDataItem so I can access the "Cells".

Upvotes: 2

Views: 5977

Answers (7)

NoWar
NoWar

Reputation: 37633

Try something like this:

private object GetData(ProfilePropertyDefinition lProfileProperty)
{
    var result = from r in gServiceContext.CreateQuery("opportunity")
                 join c in gServiceContext.CreateQuery("contact") on ((EntityReference)r["new_contact"]).Id equals c["contactid"] into opp
                 from o in opp.DefaultIfEmpty()
                 where ((EntityReference)r["new_channelpartner"]).Id.Equals(lProfileProperty.PropertyValue) && ((OptionSetValue)r["new_leadstatus"]).Equals("100000002")
                 select new    
                 {
                     OpportunityId = !r.Contains("opportunityid") ? string.Empty : r["opportunityid"],
                     CustomerId = !r.Contains("customerid") ? string.Empty : ((EntityReference)r["customerid"]).Name,
                     Priority = !r.Contains("opportunityratingcode") ? string.Empty : r.FormattedValues["opportunityratingcode"],
                     ContactName = !r.Contains("new_contact") ? string.Empty : ((EntityReference)r["new_contact"]).Name,
                 });

                 return result.ToList();
    }

and

foreach (var lItem in List<object>GetData(lProfileProperty))
{
}

and add some class

select new  [YouClassView]  
                 {
                     OpportunityId = !r.Contains("opportunityid") ? string.Empty : r["opportunityid"],
                     Custo

Upvotes: 0

Brad
Brad

Reputation: 1529

You need to return a type of GetData() that implements IEnumerable. I suggest chaining object in the method signature to IEnumerable.

IEnumerable contains a method GetEnumerator() which allows the foreach loop to work.

Upvotes: 2

abatishchev
abatishchev

Reputation: 100248

You need to return IEnumerable<Some> to be able loop over it. Currently you return just object.

But you can't return an anonymous type from a method, so you need to declare a specific type:

class Foo
{
    ...
}

private IEnumereable<Foo> GetDate()
{
    return ...
           select new Foo
           {
               ...
           };
};

Upvotes: 0

Samuel Slade
Samuel Slade

Reputation: 8613

You are getting the error because the variable received from GetData(...) is of type object. You cannot enumerate an object because it is what it is - an object and not a collection. To enumerate the result of the method call, you need to cast the object into a type that is a collection, and therefore has a GetEnumerator(...) method.

Upvotes: 1

jere
jere

Reputation: 4304

your method is returning object, not a collection or list of any kind

Upvotes: 1

Jon
Jon

Reputation: 437336

The compiler is telling you what the problem is: you cannot iterate over something that has a static type of object. Fix the return type of your GetData method to return something that implements IEnumerable.

Since you are returning a sequence of an anonymous type, you could do this simply by changing the code to

private IEnumerable GetData(ProfilePropertyDefinition lProfileProperty) 

However, you would then be unable to access the properties in the objects except by reflection. To fix that as well, you need to create a new class and return instances of that. For example:

class Foo {
    public string OpportunityId { get; set; }
    public string CustomerId { get; set; }
    public string Priority { get; set; }
    public string ContactName { get; set; }
}

and then

private IEnumerable<Foo> GetData(ProfilePropertyDefinition lProfileProperty) {
   // ...
   select new Foo
       { 
           OpportunityId = !r.Contains("opportunityid") ? string.Empty : r["opportunityid"], 
           CustomerId = !r.Contains("customerid") ? string.Empty : ((EntityReference)r["customerid"]).Name, 
           Priority = !r.Contains("opportunityratingcode") ? string.Empty : r.FormattedValues["opportunityratingcode"], 
           ContactName = !r.Contains("new_contact") ? string.Empty : ((EntityReference)r["new_contact"]).Name, 
       }; 
    // ...
}

Upvotes: 5

Justin Niessner
Justin Niessner

Reputation: 245399

Your method returns an object. object doesn't implement IEnumerable<T>. You're also not going to be able to cast to IEnumerable<T> because your method uses an anonymous type.

Your only option is to create a concrete class for the return type of the method.

Upvotes: 3

Related Questions