如何编写这种通用类型C#片段?

时间:2009-07-24 03:15:31

标签: c# generics

每种实体类型的简化重复代码是

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
}

2 个答案:

答案 0 :(得分: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 ... duh。

如果您拥有正确的继承结构(见下文),则编译良好。

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

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

答案 1 :(得分: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;
}