return 不同 return 类型的方法
methods that are returning different return types
我有以下方法,它们是 return 不同的实体,此外这些方法的输入参数都是相同的,我在条件
中使用这些方法
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);
}
还有其他类似的方法
我正在寻找一种方法来在所有这些方法中创建通用的泛型方法,但使用不同的 return 类型,但无法弄清楚。我正在将 .Net 核心与 EF 核心一起使用
如果有人对此提出任何想法,我将不胜感激,在此先感谢
我想您会发现您当前的设计是最干净的。您的代码并不完全 "generic",因为它们来自不同的 table 并且具有不同的 where 子句(例如 s.EnvironmentSource.Name == source
与 s.LightingSource.Name == source
)。
您可能能够组合一些功能,例如,按类型通用化table访问并结合过滤器的 s.Category == category
部分,但是你将混合使用反射(或 switch 语句)和泛型,它们可能比你现在拥有的更丑陋。
如果您只想使用 one 方法,也许您可以使用泛型,正如@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;
}
然后您可以调用指定 return 类型的方法:
Fields<IQueryable<LibraryEnvironment>>("a", "b", "c");
Fields<IQueryable<LibraryEquipment>>("a", "b", "c");
Fields<IQueryable<LibraryLighting>>("a", "b", "c");
您可以在 DbContext
上使用 Set<T>
方法来一般访问集合。如果将过滤所依据的所有相关属性放入一个基类中,则可以将泛型参数限制为该基类,并且仍然对所有属性进行过滤。
所以根据您的原始查询,您的 类 看起来像这样:
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);
}
你会这样调用这个方法:
public void Consumer()
{
var queryable = Fields<LightingEquipment>("spaceFunction", "category", "source", x => x.LightingSource.Name);
}
我有以下方法,它们是 return 不同的实体,此外这些方法的输入参数都是相同的,我在条件
中使用这些方法 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);
}
还有其他类似的方法
我正在寻找一种方法来在所有这些方法中创建通用的泛型方法,但使用不同的 return 类型,但无法弄清楚。我正在将 .Net 核心与 EF 核心一起使用
如果有人对此提出任何想法,我将不胜感激,在此先感谢
我想您会发现您当前的设计是最干净的。您的代码并不完全 "generic",因为它们来自不同的 table 并且具有不同的 where 子句(例如 s.EnvironmentSource.Name == source
与 s.LightingSource.Name == source
)。
您可能能够组合一些功能,例如,按类型通用化table访问并结合过滤器的 s.Category == category
部分,但是你将混合使用反射(或 switch 语句)和泛型,它们可能比你现在拥有的更丑陋。
如果您只想使用 one 方法,也许您可以使用泛型,正如@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;
}
然后您可以调用指定 return 类型的方法:
Fields<IQueryable<LibraryEnvironment>>("a", "b", "c");
Fields<IQueryable<LibraryEquipment>>("a", "b", "c");
Fields<IQueryable<LibraryLighting>>("a", "b", "c");
您可以在 DbContext
上使用 Set<T>
方法来一般访问集合。如果将过滤所依据的所有相关属性放入一个基类中,则可以将泛型参数限制为该基类,并且仍然对所有属性进行过滤。
所以根据您的原始查询,您的 类 看起来像这样:
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);
}
你会这样调用这个方法:
public void Consumer()
{
var queryable = Fields<LightingEquipment>("spaceFunction", "category", "source", x => x.LightingSource.Name);
}