Generic LINQ TO SQL Query

2019-08-31 08:48发布

问题:

Lets say I have two L2S classes generated by the designer with one property as follows:

public class A
{
  public bool IsActive {get;set;}
}

public class B
{
  public bool IsActive {get;set;}
}

I have a generic DataAccess class as follows:

public class DataAccessBase<T> where T : class 
    {
        NWDataContext dataContext = new NWDataContext();

        public IList<T> GetAllActive()
        {
            return dataContext.GetTable<T>()
                   .where(T.IsActive == true) -----> How can i do something like this?
                   .ToList<T>();
        }
   }

Now from the GetAllActive() how can I return all active objects of either A or B type. My guess is that I have to use reflection to do this but I am very new to reflection. Can anyone point me in the right direction?

回答1:

What you need to pass to Enumerable.Where is a Predicate<T>. A Predicate<T> is a delegate that can eat instances of T and return a bool; you can think of a predicate as representing a property that is either true or false about instaces of T.

Now, there is a larger issue which is that unless you put a constraint on T, the compiler has no way of knowing that T has a publicly readable property named IsActive. Thus, you have to define an interface (or a base class) that both A and B implement (or derive from) and tell the method GetAllActive that T implements (or derives from) this interface (or base class). You can do this by constraining T in the definition of DataAccessBase. Thus:

interface IIsActive {
    bool IsActive { get; set; }
}

class A : IIsActive {
    public bool IsActive { get; set; }
}
class B : IIsActive {
    public bool IsActive { get; set; }
}

public class DataAccessBase<T> where T : class, IIsActive {
    public IList<T> GetAllActive() {
    return dataContext.GetTable<T>()
                      .Where(x => x.IsActive)
                      .ToList();
    }
}


回答2:

You need to assert that T implements an interface that defines isActive

public interface IIsActive
{
    bool IsActive { get; set; }
}

public class DataAccessBase<T> where T : IIsActive