需要帮助简化使用泛型在C#方法
我有这样一个功能下加载使用LinqToSql数据库表,并返回转化为我的自定义模型类的条目列表:需要帮助简化使用泛型在C#方法
public List<AreaModel> LoadListOfAreaModels(Boolean includeDeleted = false)
{
using (LinqToSqlDataContext dc = new LinqToSqlDataContext())
{
IQueryable<Areas> filtered = includeDeleted
? dc.Areas.Where((c) => !c.DataRowDeleted)
: dc.Areas;
return filtered.Select((c) => AreaModel.ModelFactoryFromLinq(c)).ToList();
}
}
现在我有相当多的表格,并且都必须以相同的方式加载和转换。
我能以某种方式避免输入此功能十几次,只是将AreaModel
和Areas
更改为例如TownModel
和Towns
通过使用通用函数?
我已经试过这个,但失败了,因为我找不到调用静态类方法的方法,如果我只有它的泛型类型参数。
进一步信息:(!不包含静态工厂方法,我需要调用,虽然)所有XxxModel
类具有共同的超ModelBase
,所有的LINQ表类(如Areas
或Towns
)实现公共接口ILinqClass
。
关于如何实现这个最优雅的方式的任何想法?
通过knittl的回答启发,我想出了这个解决方案:
public List<TModel> LoadListOfModels<TLinq, TModel>(
Func<TLinq, bool> filter,
Func<TLinq, TModel> modelFactory
)
where TLinq : class, ILinqClass
where TModel : ModelBase
{
using (LinqToSqlDataContext dc = new LinqToSqlDataContext())
{
return dc.GetTable<TLinq>()
.Where(filter)
.Select(modelFactory)
.ToList();
}
}
您应该能够通过代表/ funcs中:
public List<TModel> LoadListOfModels<TDbModel, TModel>(
Func<LinqToSqlDataContext, TDbModel> modelSelector,
Func<TDbModel, bool> isDeleted,
Func<TDbModel, TModel> modelFactory,
bool includeDeleted = false)
{
using (LinqToSqlDataContext dc = new LinqToSqlDataContext())
{
var models = modelSelector(dc);
var filtered = includeDeleted
? models.Where(c => !isDeleted(c))
: models;
return filtered.Select(modelFactory).ToList();
}
}
对于Area
通话如下:
LoadListOfModels(
dc => dc.Areas,
c => c.DataRowDeleted,
Area.ModelFactoryFromLinq,
includeDeleted);
为Town
:
LoadListOfModels(
dc => dc.Towns,
c => c.DataRowDeleted,
Town.ModelFactoryFromLinq,
includeDeleted);
你甚至可能能够摆脱includeDeleted
参数。只需通过一个过滤器功能Func<TDbModel, bool> filter
。
return modelsSelector(dc)
.Where(filter)
.Select(modelFactory)
.ToList();
电话:
LoadListOfModels(dc => dc.Areas, c => true, Area.ModelFactoryFromLinq);
LoadListOfModels(dc => dc.Areas, c => !c.DataRowDeleted, Area.ModelFactoryFromLinq);
谢谢,我设法摆脱了modelSelector参数,请参阅我编辑的问题以获得最终方法。 –
试试这个办法:
public abstract class BaseClass<TModel> where TModel : class
{
public bool DataRowDeleted { get; set; }
public abstract TModel ModelFactoryFromLinq();
}
public class Area : BaseClass<AreaModel>
{
public override AreaModel ModelFactoryFromLinq()
{
return new AreaModel();
}
}
public static List<TModel> LoadListOfAreaModels<TContext, TModel>(bool includeDeleted = false)
where TContext : BaseClass<TModel>, new()
where TModel : class
{
using (var dc = new LinqToSqlDataContext())
{
IQueryable<TContext> filtered = includeDeleted
? dc.GetTable<TContext>().Where((c) => !c.DataRowDeleted)
: dc.GetTable<TContext>();
return filtered.Select((c) => c.ModelFactoryFromLinq()).ToList();
}
}
实现:
List<AreaModel> result = SomeClassName.LoadListOfAreaModels<Area, AreaModel>();
如果DataRowDeleted
定义在ModelBase
你应该能够做到:
public static IQueryable<TModel> LoadListOfQuery<T, TModel>(IQueryable<T> source, Expression<Func<T, TModel>> selector, bool includeDeleted = false) where T : ModelBase {
IQueryable<T> filtered = includeDeleted ? source : source.Where(s => !s.DataRowDeleted);
return filtered.Select(selector);
}
然后添加一个函数来计算给定语境的查询:
public static List<T> ExecList(Func<LinqToSqlDataContext, IQueryable<T>> qf)
{
using(var c = new LinqToSqlDataContext())
{
var q = qf(c);
return q.ToList();
}
}
然后,你可以这样做:
public List<AreaModel> LoadListOfAreaModels(bool includeDeleted = false)
{
ExecList(c => LoadListOfQuery(c.Areas, a => AreaModel.ModelFactoryFromLinq(a), includeDeleted);
}
是'DataRowDeleted'在ModelBase中定义? – Lee
@Lee是的,'DataRowDeleted'它是'ModelBase'的一个接口的一部分implements –
你提到的问题是AreaModel是一个静态类。你为什么不试着让你的AreaModel,TownModel成为一个非静态类?然后他们可以用一个方法ModelFactoryFromLinq实现一个接口,就像IModelFactory一样,然后你可以将一个实现传递给你的LoadList方法的接口。 –