C# 返回不同返回类型的方法

C# 返回不同返回类型的方法,c#,.net,entity-framework,linq,dynamic-linq,C#,.net,Entity Framework,Linq,Dynamic Linq,我有下面的方法,它们返回不同的实体,此外,这些方法的输入参数都是相同的,我在where条件下使用这些参数 public IQueryable<LibraryEnvironment> EnvironmentFields(string spaceFunction, string category, string source) { return _dbContext.LibraryEnvironment.Where(s => s.SpaceFuncti

我有下面的方法,它们返回不同的实体,此外,这些方法的输入参数都是相同的,我在where条件下使用这些参数

   public IQueryable<LibraryEnvironment> EnvironmentFields(string spaceFunction, string category, string source)
    {
        return _dbContext.LibraryEnvironment.Where(s => s.SpaceFunction == spaceFunction
                                                                && s.Category == category &&
                                                                 s.EnvironmentSource.Name == source);
    }

    public IQueryable<LibraryEquipment> EquipmentFileds(string spaceFunction, string category, string source)
    {
        return _dbContext.LibraryEquipment.Where(s => s.SpaceFunction == spaceFunction
                                                              && s.Category == category &&
                                                               s.EquipmentSource.Name == source);
    }

    public IQueryable<LibraryLighting> LightingFields(string spaceFunction, string category, string source)
    {
        return _dbContext.LibraryLighting.Where(s => s.SpaceFunction == spaceFunction
                                                             && s.Category == category &&
                                                              s.LightingSource.Name == source);
    }
publicIQueryable环境字段(字符串空间函数、字符串类别、字符串源)
{
返回_dbContext.LibraryEnvironment.Where(s=>s.SpaceFunction==SpaceFunction
&&美国类别==类别&&
s、 EnvironmentSource.Name==source);
}
公共IQueryable设备文件(字符串空格函数、字符串类别、字符串源)
{
返回_dbContext.LibraryEquipment.Where(s=>s.SpaceFunction==SpaceFunction
&&美国类别==类别&&
s、 设备源。名称==源);
}
公共IQueryable LightingFields(字符串空格函数、字符串类别、字符串源)
{
返回_dbContext.LibraryLighting.Where(s=>s.SpaceFunction==SpaceFunction
&&美国类别==类别&&
s、 LightingSource.Name==光源);
}
还有其他类似的方法

我正在寻找一种方法,在所有这些方法中创建通用的泛型方法,但返回类型不同,无法找到解决方法。我正在使用.Net core和EF core


如果有人对此提出任何建议,我将非常感谢,提前感谢

我想你会发现你目前的设计是最干净的。您的代码不是完全“通用”的,因为它们来自不同的表,并且具有不同的where子句(例如
s.EnvironmentSource.Name==source
vs
s.LightingSource.Name==source


例如,您可以通过按类型泛化表访问和组合过滤器的
s.Category==Category
部分来组合一些功能,但是您将混合使用反射(或switch语句)泛型可能比你现在拥有的更丑陋。

如果你只想拥有一个方法,也许你可以不使用泛型,正如@ColinM在检查类型以决定执行哪个代码块时提到的那样。
还没有测试过,可能是错误的方法。这取决于你在哪里使用它

public T Fields<T>(string spaceFunction, string category, string source)
{
    Type tt = typeof(T);
    if(tt == typeof(IQueryable<LibraryEnvironment>))
        return _dbContext.LibraryEnvironment.Where(s => s.SpaceFunction == spaceFunction
                                                        && s.Category == category &&
                                                          s.EnvironmentSource.Name == source);
    if (tt == typeof(IQueryable<LibraryEquipment>))
        return _dbContext.LibraryEquipment.Where(s => s.SpaceFunction == spaceFunction
                                                      && s.Category == category &&
                                                        s.EquipmentSource.Name == source);
    if (tt == typeof(IQueryable<LibraryLighting>))
        return _dbContext.LibraryLighting.Where(s => s.SpaceFunction == spaceFunction
                                                      && s.Category == category &&
                                                      s.LightingSource.Name == source);
    return default;
}
公共T字段(字符串空格函数、字符串类别、字符串源)
{
类型tt=类型(T);
如果(tt==typeof(IQueryable))
返回_dbContext.LibraryEnvironment.Where(s=>s.SpaceFunction==SpaceFunction
&&美国类别==类别&&
s、 EnvironmentSource.Name==source);
如果(tt==typeof(IQueryable))
返回_dbContext.LibraryEquipment.Where(s=>s.SpaceFunction==SpaceFunction
&&美国类别==类别&&
s、 设备源。名称==源);
如果(tt==typeof(IQueryable))
返回_dbContext.LibraryLighting.Where(s=>s.SpaceFunction==SpaceFunction
&&美国类别==类别&&
s、 LightingSource.Name==光源);
返回默认值;
}
然后可以调用指定返回类型的方法:

Fields<IQueryable<LibraryEnvironment>>("a", "b", "c");
Fields<IQueryable<LibraryEquipment>>("a", "b", "c");
Fields<IQueryable<LibraryLighting>>("a", "b", "c");
字段(“a”、“b”、“c”);
字段(“a”、“b”、“c”);
字段(“a”、“b”、“c”);
您可以使用
DbContext
上的
Set
方法对集合进行常规访问。如果将筛选所依据的所有相关属性放入一个基中,则可以将泛型参数约束到该基类型,并且仍然对所有属性进行筛选

因此,基于原始查询,您的类看起来像这样:

public class Entity
{
    public string SpaceFunction { get; set; }
    public string Category { get; set; }
}

public class LightingEquipment : Entity
{
    public LightingSource LightingSource { get; set; }
}

public class LightingSource
{
    public string Name { get; set; }
}
您的方法是这样的,使用源选择器:

public IQueryable<T> Fields<T>(string spaceFunction, string category, string source, Func<T, string> sourceSelector) where T : Entity
{
    return _dbContext.Set<T>().Where(s => s.SpaceFunction == spaceFunction
                              && s.Category == category &&
                              sourceSelector(s) == source);
}
公共IQueryable字段(字符串空格函数、字符串类别、字符串源、函数源选择器),其中T:Entity
{
返回_dbContext.Set(),其中(s=>s.SpaceFunction==SpaceFunction
&&美国类别==类别&&
源选择器==源;
}
您可以这样调用此方法:

public void Consumer()
{
    var queryable = Fields<LightingEquipment>("spaceFunction", "category", "source", x => x.LightingSource.Name);
}
public void Consumer()
{
var queryable=字段(“spaceFunction”、“category”、“source”,x=>x.LightingSource.Name);
}

看一看,您可以接受一个
表达式
来引入一个选择器,允许您选择
s.EnvironmentSource
s.EquipmentSource
s.LightningSource
@ColinM您能提供一些非常感谢的示例代码吗
s.EnvironmentSource
s.EquipmentSource
s.LightingSource
有一个共同的基类型还是什么?我看到这三个表都有一个
名称
属性。@Sweeper是的,它们都来自一个表,并根据我们使用它们的实体对其进行了重命名哦,所以它们都是相同的类型?那么它是什么类型的呢?非常感谢您的建议,我对switch语句表示同意,但是如果您从这里传递实体
字段(“a”、“b”、“c”)
,并且在方法
字段中
是否可以删除该if条件。。或任何其他方式
字段(“a”、“b”、“c”)
优于
环境字段(“a”、“b”、“c”)
?即使您将可查询部分泛化,您仍然只有`
字段(“a”、“b”、“c”)
,这并不比原来的好。
环境字段
将是“硬编码的”。我觉得有点好