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

时间:2021-05-06 19:47:46

Simplified repeated code for each entity type is

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

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();
}

I wanted to create a generic function that creates the query, but not sure how to go about it?

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

ie in the following snippet, How do I code for ReturnAGenericQuery?

即在下面的代码片段中,我如何为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 个解决方案

#1


Your example is a little vague, but it looks like you need something along the lines of:

你的例子有点模糊,但看起来你需要的东西是:

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();
}

The reason you need the 'where T :' clause is because T needs to be a type that has a property 'Id' for your LINQ where-clause to work ... so you'd need to derive Entity1 and Entity2 from a base class that defines that property. If you need any other properties for the 'other stuff' these will need to be added to the base class too.

你需要'where T:'子句的原因是因为T需要是一个具有属性'Id'的类型,你的LINQ where子句才能工作......所以你需要从一个基础派生Entity1和Entity2定义该属性的类。如果你需要“其他东西”的任何其他属性,那么这些属性也需要添加到基类中。

Addendum:
If context.entity1 (whatever collection that refers to) is not an IQueryable<entity1>, then you may need to use context.entity1.AsQueryable() instead.

附录:如果context.entity1(引用的任何集合)不是IQueryable ,那么您可能需要使用context.entity1.AsQueryable()。

Originally my query was wrong, it was supposed to query from refDataType in source rather than in result... duh.

最初我的查询是错误的,它应该从源代码中的refDataType查询而不是结果... duh。

Provided you have the right kind of inheritance structure (see below), this compiles fine.

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

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

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

#2


You need an interface.

你需要一个界面。

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;
}

#1


Your example is a little vague, but it looks like you need something along the lines of:

你的例子有点模糊,但看起来你需要的东西是:

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();
}

The reason you need the 'where T :' clause is because T needs to be a type that has a property 'Id' for your LINQ where-clause to work ... so you'd need to derive Entity1 and Entity2 from a base class that defines that property. If you need any other properties for the 'other stuff' these will need to be added to the base class too.

你需要'where T:'子句的原因是因为T需要是一个具有属性'Id'的类型,你的LINQ where子句才能工作......所以你需要从一个基础派生Entity1和Entity2定义该属性的类。如果你需要“其他东西”的任何其他属性,那么这些属性也需要添加到基类中。

Addendum:
If context.entity1 (whatever collection that refers to) is not an IQueryable<entity1>, then you may need to use context.entity1.AsQueryable() instead.

附录:如果context.entity1(引用的任何集合)不是IQueryable ,那么您可能需要使用context.entity1.AsQueryable()。

Originally my query was wrong, it was supposed to query from refDataType in source rather than in result... duh.

最初我的查询是错误的,它应该从源代码中的refDataType查询而不是结果... duh。

Provided you have the right kind of inheritance structure (see below), this compiles fine.

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

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

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

#2


You need an interface.

你需要一个界面。

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;
}