我有以下代码返回包含Id字段和Name字段的数据库表的结果,并将其传输到SelectListItems列表(这会在我的视图中填充一个下拉框。)
var locationTypes = await APIHelper.GetAsync<List<LocationType>>(url);
var items = new List<SelectListItem>();
items.AddRange(locationTypes.Select(locationType =>
{
var item = new SelectListItem();
item.Value = locationType.LocationTypeId.ToString();
item.Text = locationType.Name;
return item;
}));
我在整个应用程序中重复了很多,用LocationType替换了其他各种东西。 item.Value始终获取返回数据的Id属性(Id字段始终采用{TableName} +“Id”的格式),而item.Text始终获取“.Name”属性。
我怎样才能使这个通用?我试图实现这样的东西,虽然它在语法上是不正确的,可能是不正确的方法:
var myGenericObjects = await APIHelper.GetAsync<List<T>>(url)
var items = new List<SelectListItem>();
items.AddRange(myGenericObjects .Select(myGenericObjects =>
{
var item = new SelectListItem();
item.Value = myGenericObject.Field[0].ToString();
item.Text = myGenericObject.Name;
return item;
}));
答案 0 :(得分:2)
您可以为通用列表对象创建自定义扩展,然后使用反射检索要映射到SelectListItem.Text和Name字段的值。注意我正在使用&#34; nameof&#34;为了防止我试图映射的属性的任何混淆或魔术字符串表示。
我确实定义了一个默认值&#34; Name&#34;到namePropertyName参数。根据您的描述,按照惯例,大多数您的DTO都拥有属性&#34; Name&#34;在他们中。如果不是这种情况,只需删除已定义的默认值。
可以对此扩展进行其他检查以防止NullReference和ArgumentExceptions,但为了简化示例,我们将其排除在外。示例:确保在idPropertyName和namePropertyName参数中提供值,并确保在转换之前在提供的通用对象上存在这些属性名称。
public static class ListExtensions
{
public static List<SelectListItem> ToSelectList<T>(this List<T> list, string idPropertyName, string namePropertyName = "Name")
where T : class, new()
{
List<SelectListItem> selectListItems = new List<SelectListItem>();
list.ForEach(item =>
{
selectListItems.Add(new SelectListItem
{
Text = item.GetType().GetProperty(namePropertyName).GetValue(item).ToString(),
Value = item.GetType().GetProperty(idPropertyName).GetValue(item).ToString()
});
});
return selectListItems;
}
}
使用示例:
var testList = new List<TestDto>
{
new TestDto { Name = "Test0", TestId = 0 },
new TestDto { Name = "Test1", TestId = 1 },
new TestDto { Name = "Test2", TestId = 2 },
new TestDto { Name = "Test3", TestId = 3 },
new TestDto { Name = "Test4", TestId = 4 },
};
var selectList = testList.ToSelectList(nameof(TestDto.TestId), nameof(TestDto.Name));
以下是TestDto类供参考:
public class TestDto
{
public int TestId { get; set; }
public string Name { get; set; }
}
答案 1 :(得分:0)
一些准备工作
如果可以更改表列名称,则使用约定。例如,始终将&#34; Value&#34;命名为栏&#34; X&#34;和&#34;文字&#34;栏&#34; Y&#34; (给他们更好的名字)。然后使这些表的所有类实现类似于此的接口:
public interface ICustomLookup
{
string X { get; set; }
string Y { get; set; }
}
public class SomeClass : ICustomLookup
{
public string X { get; set; }
public string Y { get; set; }
}
然后像这样的扩展方法:
public static class EnumerableExtension
{
public static SelectList ToSelectList(this IEnumerable<ICustomLookup> items)
{
return new SelectList(items.Select(thisItem => new SelectListItem
{
Text = thisItem.X,
Value = thisItem.Y
}));
}
}
<强>用法强>
var items = new List<SomeClass>
{
new SomeClass { X = "XOne", Y = "YOne" },
new SomeClass { X = "XTwo", Y = "YTwo" }
};
SelectList selectList = items.ToSelectList();