2009-07-24 76 views
0

为每个实体类型简化重复的代码是如何编写这个泛型类型的C#代码片段?

public IList<entity1> GetEntity1(.. query params ..) 
{ 
    IQueryable<entity1> query = context.entity1; 

    query = from refDataType in query 
      where refDataType.Id > 0 
      select refDataType; 
    . 
    . plus more changes to query same for each entity 
    . 

    return query.ToList(); 
} 

我想创建一个用于创建查询的通用功能,但不知道如何去做?

即在下面的代码片段中,如何为ReturnAGenericQuery编码?

public IList<entity1> GetEntity1(.. query params ..) 
{ 
    IQueryable<entity1> query = context.entity1;  
    query = ReturnAGenericQuery of type entity1 
    return query.ToList(); 
} 

public IList<entity2> GetEntity2(.. query params ..) 
{ 
    IQueryable<entity2> query = context.entity2;  
    query = ReturnAGenericQuery of type entity2 
    return query.ToList(); 
} 

private IQueryable<T> ReturnAGenericQuery<T>() 
{ 
    return IQueryable of entity1 or entity2 
} 

回答

3

你的例子是有点模糊,但它看起来像你需要沿着线的东西:

private IQueryable<T> ReturnAGenericQuery<T>(IQueryable<T> source) 
    where T : SomeBaseTypeForAllYourEntities 
{ 
    IQueryable<T> result = 
     from refDataType in source 
     where refDataType.Id > 0 
     select refDataType; 

    // Other stuff here 

    return result; 
} 

public IList<Entity1> GetEntity1(...) 
{ 
    return ReturnAGenericQuery(context.entity1).ToList(); 
} 

您需要的“where T :”条款是因为T需要是一个类型的原因有一个属性'Id'为您的LINQ where子句工作...所以你需要从定义该属性的基类派生Entity1和Entity2。如果您需要“其他内容”的任何其他属性,则这些内容也需要添加到基类中。

附录:
如果context.entity1(指代任何集合)不是IQueryable<entity1>,那么你可能需要使用context.entity1.AsQueryable()来代替。

本来我的查询是错误的,它应该查询from refDataType in source而不是in result ...呃。

只要你有正确的继承结构(见下文),这个编译好。

public class SomeBaseTypeForAllYourEntities 
{ 
    public int Id { get; set; } 
} 

sealed public class Entity1 : SomeBaseTypeForAllYourEntities 
{ 
    ... other properties, etc. ... 
} 
+0

这将不会编译(即使你给'源'和'查询'相同的名称),直到你给该方法一个第二类型参数。 'result'是IQueryable ,它与实体类型T不一样。 – 2009-07-24 13:09:32

+0

有一个'AsQueryable()'丢失,并且在我的查询中有一个错字,但除此之外,这个编译很好...增加了一些更详细的内容,以便绝对清楚。 – jerryjvl 2009-07-24 15:12:21

1

您需要一个接口。

private IQueryable<T, R> ReturnAGenericQuery<T> (T entity) where T : IQueryable, IHasRefDataType 
{ 
    return from DataType refDataType in entity 
      where refDataType.Id > 0 
      select refDataType; 
} 

struct DataType 
{ 
    public int Id; 
} 

public interface IHasRefDataType 
{ 
    DataType refDataType; 
}