Customizing IQuaryable<T> RRS feed

  • Question

  • I'm trying to customize entities of my application to make them have a property referencing the DataContext that loaded them.

    I think the best way is to somehow create a class that implements the IQuaryable<T> and set the entity datacontext property in its GetEnumerator method.

    My question is, how can I use the Provider and Expression used by Linq to SQL in my implementation of IQueryable<T> so that I don't have to implement them myself?

     BTW: For my scenario, is there another way?


    Tuesday, January 27, 2009 4:39 PM

All replies

  • You could make an extension method instead, with a method signature like:

    public static MyDataContext GetDataContext(this IQueryable<T>) { }

    That's the way I would suggest doing this instead of making an entirely new class.
    Tuesday, January 27, 2009 5:08 PM
  • Your solution will not solve my problem. Because I want each item of sequence, returned from linq query to have its DataContext property set.

    Take a look at the following code:

    public partial class Product: IEntityBase  
        public Product() 
            _DataContext = new SampleDataContext(); 
        private long _Id;  
        [Column(Storage="_Id", AutoSync=AutoSync.OnInsert, DbType="BigInt NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]  
        public long Id  
             getreturn _Id; }  
             set{ _Id = value; }  
        private string _Name;  
        [Column(Storage="_Name", DbType="NVarChar(MAX) NOT NULL", CanBeNull=false  
        public string Name  
            getreturn _Name; }  
            set{ _Name = value; }  
        private SampleDataContext _DataContext;  
        //This is the property extending the Product class and should be set when this class is being returned 
        //by IQueryable<T>.GetEnumerator() 
        public SampleDataContext DataContext  
            getreturn _Name; }  
            set{ _Name = value; }  
        public MyQueryable<Product> GetProducts() 
            MyQueryable<Product> result = from p in context.Products 
                                          where {Some Conditions 1} 
                                          select p; 
            result.DataContext = _DataContext; 
            return result; 
        public void SomeMethod() 
            //This query will not actually set the DataCotnext property. 
            //And the generated sql query is something like:  
            //SELECT * FROM Products WHERE {Some Conditions 1} AND {Some Conditions 2} 
            var products = GetProducts().Where( {Some Conditions 2} ); 
            //Now that the GetEnumerator() is called the DataContext property of the products 
            //will be set. 
            foreach( var item in products ) 
                item.Name = "Test Name"
    public MyQueryable<T>: IQueryable<T> 
        where T: class, IEntityBase 
        //Implementation of IQueryable which is my question 
        public IEnumerator<T> GetEnumerator() 
            foreach( var item in Provider.GetEnumerator<T>() ) 
                item.DataContext = this.DataContext; 
                yield return item; 
        public SampleDataContext DataContext{ getset; } 
    public interface IEntityBase 
        SampleDataContext DataContext{ getset; }; 

    Wednesday, January 28, 2009 6:32 AM
  • I would suggest that you have your class have the DataContext instead and just use products.DataContext.SubmitChanges(); instead of submitting changes after every product, since that will do way more connections than you need.  It's generally a good idea to do things in larger transactions where possible.
    Daniel -
    Friday, January 30, 2009 2:37 AM