2011-04-08 183 views
0

我有几个表都具有相同的列domainID,它们基本上只是控制哪些数据显示在哪个网站上,因为它们共享数据库。传递lambda表达式作为参数

所以当我去控制一个表的数据绑定时,我需要创建一个大的开关来处理不同的LINQ查询。我想创建一个实用方法,它将表类型作为参数,然后根据传入的表中的列返回where子句。

public static IEnumerable<T> ExecuteInContext<T>(
       IQueryable<T> src) 
     { 
      int domain = 1;//hard coded for example 

      return src.Where(x => x.DomainID == domain);//Won't work, has to be a way to do this.    
     } 

我被卡在返回码上。你不能简单地构造一个像我一样的where子句,因为它不知道我在说什么表。

我试图调用第一种方法是这样的:

using (DataClasses1DataContext db = new DataClasses1DataContext()) 
     { 

      var q = Utility.ExecuteInContext(db.GetTable<item>()); 

      Repeater1.DataSource = q; 
      Repeater1.DataBind(); 
     } 

我希望这说明了什么,我试图做的。

编辑: BrokenGlass的答案解决了我的问题。我想补充一点,你需要打开你的.dbml.cs文件,并用你的界面扩展表/类。我还想指出,如果我的专栏可以为空,那么该项目不会生成,它说它与我的界面不同。

回答

3

你必须限制您的T转换为属性为DomainID的类 - 您可以将这些接口实现添加到扩展数据模型的部分类中。

public interface IFoo 
{ 
    int DomainId { get; set; } 
} 
.. 

public static IQueryable<T> ExecuteInContext<T>(IQueryable<T> src) where T: IFoo 
{ 
    int domain = 1;//hard coded for example 
    return src.Where(x => x.DomainID == domain); 
} 
+0

当我尝试调用此方法并将参数设置为我的'item'表时,它表示没有从'item'到'utility.IFoo'的显式引用转换。 – 2011-04-08 19:51:00

+0

您的item表类实现了'IFoo'吗?这对于此工作是必需的。你可能需要在分类中添加它,我使用Linq到实体 - 希望Linq到SQL也是一样,如果不是,那么忽略这个答案 – BrokenGlass 2011-04-08 19:56:06

+0

我不知道该怎么做。我现在拥有的是我的问题中的第二个代码块。 – 2011-04-08 19:58:21

0

你应该能够在您的泛型参数转换为预期的类型......

public static IEnumerable<T> ExecuteInContext<T>(IQueryable<T> src) 
{ 
    int domain = 1;//hard coded for example 

    return src.Where(x => ((T)x).DomainID == domain); 
} 

但你意识到你已经创建了一个假设其类型参数将始终暴露特定属性的通用方法是什么?如果你要做到这一点,你应该申请一个generic type constraint的是T总是来源于一种类型的这个属性...

例如:

public static IEnumerable<T> ExecuteInContext<T>(IQueryable<T> src) where T : IMyDomainObject 
+0

将调用此方法将总是有这些查询包含'domainID'列的表,如果这就是你的意思。 – 2011-04-08 19:54:30

+0

它不允许我将参数转换为预期的类型。 – 2011-04-08 20:04:07

0

我不知道如果我明白你的意思,但也许你想添加一个WHERE子句:

public static IEnumerable<T> ExecuteInContext<T>(IQueryable<T> src)  

    where T: MyType //MyType exposing your DomainId 
    {    
     int domain = 1;//hard coded for example    
     return src.Where(x => x.DomainID == domain);//Won't work, has to be a way to do this.      
    } 
2
Expression pe = Expression.Parameter(typeof(T)); 
Expression prope = Expression.Property(pe, "DomainID"); 
Expression ce = Expression.Equals(prope, 
    Expression.Constant((int)1); 

Expression<Func<T,bool>> exp = 
Expression.Lambda<Func<T,bool>>(
    ce, pe); 

return query.Where(exp); 
+0

这看起来很可怕但很有趣 - 所以这种方法可以工作,不管T是什么类型,如果它有一个属性'DomainID'? – BrokenGlass 2011-04-08 19:58:23

+0

是的,如果你使用反射器,这正是编译器所做的。 – 2011-04-09 05:00:13

相关问题