我使用通用方法来填充所有类型的下拉列表
下面是我的代码。
实体类型如下
public class Role
{
public string Id { get; set; }
public string Name { get; set; }
}
public class DropDown
{
public string Id { get; set; }
public string Name { get; set; }
}
我能够在
成功获取数据
var data = DataFetcher.FetchData<T>();
private static void Main( string[] args )
{
List<DropDown> cities = BLL.GetDataList<City>();
List<DropDown> states = BLL.GetDataList<State>();
List<DropDown> roles = BLL.GetDataList<Role>();
}
public static class BLL
{
public static List<DropDown> GetDataList<T>() where T : class ,new()
{
var data = DataFetcher.FetchData<T>();
return data as List<DropDown>;
}
}
我知道这个演员data as List<DropDown>
会失败,这就是为什么它将null返回给调用方法,
如何将通用列表转换为已知类型列表?
答案 0 :(得分:3)
您必须问自己:我如何将T
转换为DropDown
?如果你不能回答这个问题,答案是:你不能。
我猜测您的DropDown
类有object Value
属性,其中包含下拉值,您希望将数据实体分配给该属性。
然后您可以将数据实体列表投影到DropDown
,如下所示:
var data = DataFetcher.FetchData<T>();
return data.Select(d => new DropDown { Value = d }).ToList();
至于您的修改:因此您至少有一种类型,即显示的Role
,具有Id
和Name
属性。但是T
类型并不能保证这一点,因此您需要引入一个界面:
public interface INamedIdentifyableEntity
{
string Id { get; set; }
string Name { get; set; }
}
并将其应用于您的实体。然后将其作为通用约束引入并进行映射:
return data.Select(d => new DropDown
{
Id = d.Id,
Name = d.Name,
}).ToList();
但是你不想要这个,因为在这里你将这两个属性绑定到下拉列表。明天您需要一个Code
而不是Id
和Text
而不是Name
的实体,因此您必须添加更多接口,更多重载等等。
相反,您可能希望使用反射,您可以在其中指定调用中的成员名称:
List<DropDown> cities = BLL.GetDataList<City>(valueMember: c => c.CityCode, displayMember: c => c.FullCityname);
并使用这些成员表达式查找data
的值并将其填入DropDown
。
但是,你要重新发明轮子。完全忽略你的DropDown
课程,并将下拉代留给前端,在本例中为MVC:
var cities = DataFetcher.FetchData<City>();
var selectList = new SelectList(cities.Select(c => new SelectListItem
{
Selected = (c.Id == selectedCityId),
Text = c.FullCityName,
Value = c.CityCode,
});
或者:
var selectList = new SelectList(cities, "CityCode" , "FullCityName", selectedCityId);
答案 1 :(得分:1)
一种解决方案是使用AutoMapper。
首先在模型之间创建一个这样的地图:
AutoMapper.Mapper.CreateMap<Role, DropDown>();
如果需要,请对City
和State
类执行相同的操作。
然后您可以使用AutpMapper将对象转换为DropDown
,如下所示:
public static List<DropDown> GetDataList<T>() where T : class ,new()
{
var data = DataFetcher.FetchData<T>();
return data.Select(x => AutoMapper.Mapper.Map<DropDown>(x)).ToList();
}
答案 2 :(得分:0)
如果我正确理解了这个问题,你可以按如下方式使用Linq。
return data.Cast<DropDown>().ToList();