views:

92

answers:

2

Hi!

I'm trying to run the Count() function of a Linq statement in an overriden Gridview function. Basically, I want to be able to assign a linq query to a gridview, and on the OnDataBound(e) event in my new extended gridview have it retrieve the count, using the IQueryable.

So, I need to dynamically cast the GridView.DataSource to my LinqToSql IQueryable object so that i can execute the Count() function against it.

This is where I'm at so far:

protected override void OnDataBound(EventArgs e)
    {
        IEnumerable _data = null;
        if (this.DataSource is IQueryable)
        {
            _data = (IQueryable)this.DataSource;
        }
        System.Type dataSourceType = _data.GetType();
        System.Type dataItemType = typeof(object);
        if (dataSourceType.HasElementType)
        {
            dataItemType = dataSourceType.GetElementType();
        }
        else if (dataSourceType.IsGenericType)
        {
            dataItemType = dataSourceType.GetGenericArguments()[0];
        }
        else if (_data is IEnumerable)
        {
            IEnumerator dataEnumerator = _data.GetEnumerator();

            if (dataEnumerator.MoveNext() && dataEnumerator.Current != null)
            {
                dataItemType = dataEnumerator.Current.GetType();
            }
        }
        Object o = Activator.CreateInstance(dataItemType);
        object[] objArray = new object[] { o };
        RowCount = (int)dataSourceType.GetMethod("Count").Invoke(_data, objArray);

Any ideas? I'm really new with working with IQueryables and Linq so I may be way off. How can I get my _data to allow me to run the Count function?

A: 

change this

Object o = Activator.CreateInstance(dataItemType);
    object[] objArray = new object[] { o };
    RowCount = (int)dataSourceType.GetMethod("Count").Invoke(_data, objArray);

to this

RowCount = (int)_data.OfType<object>().Count();
Micah
Because `_data` is of type `IEnumerable`, this will not execute inside the DB. Instead, you will pull back the entire table and iterate over it to get the count.
kvb
+1  A: 

This is probably the easiest way (and is somewhat related to your own answer):

protected override void OnDataBound(EventArgs e) {
    var count = 0;
    if (DataSource is IQueryable) {
        count = ((IQueryable)DataSource).OfType<object>().Count();
    }
    else {
        count = ((IEnumerable)DataSource).OfType<object>().Count();
    }

    // use count here
}

Assuming that the query provider is intelligent enough to ignore the conversion to object, this should result in a DB query to get the count if the source is actually an IQueryable.

kvb