在Linq查询使用动态显示名称作为别名从实体
我有如下Manufacturer
实体:在Linq查询使用动态显示名称作为别名从实体
class Manufacturer
{
[Key]
public int Id { get; set; }
[DisplayName("Manufacturer Code")]
public int Code { get; set; }
[DisplayName("Manufacturer Name")]
public string Name { get; set; }
}
正如你看到的每一个申请都DisplayName
数据注解。在正常的方式通过我下面的代码选择制造商表中的行:
dataGridView1.DataSource = DatabaseContext.Set<Manufacturer>()
.Select(m => new
{
Id = m.Id,
Code = m.Code,
Name = m.Name,
})
.ToList();
我想找到一种方式,把动态显示名称为Linq查询别名。
我想我一定是生成查询像一个方法:
dataGridView1.DataSource = DatabaseContext.Set<Manufacturer>()
.Select(m => new
{
Id = m.Id,
[Manufacturer Code] = m.Code,
[Manufacturer Name] = m.Name,
})
.ToList();
我可以通过下面的代码获得所有DisplayName
:
public static Dictionary<string, string> GetEntityDisplayName(this Type type)
{
return TypeDescriptor.GetProperties(type)
.Cast<PropertyDescriptor>()
.ToDictionary(p => p.Name, p => p.DisplayName);
}
,但不知道如何做到这一点。有什么办法可以把DisplayName
作为的别名动态查询吗?
更新: 作为答案之一,当使用.ToList
获取各行从实体交回该项目与DisplayNameAttribute
,但新事物的模型的列表说的是当创建的LINQ查询使用2实体,列出项目在查询中您确切说的行。例如:
class Manufacturer
{
[Key]
public int Id { get; set; }
[DisplayName("Manufacturer Code")]
public int Code { get; set; }
[DisplayName("Manufacturer Name")]
public string Name { get; set; }
}
和:
class Good
{
[Key]
[DisplayName("ID")]
public int Id { get; set; }
[DisplayName("Good Name")]
public string Name { get; set; }
public int? ManufacturerId { get; set; }
public virtual Manufacturer Manufacturer { get; set; }
}
和查询:
using (AppDbContext db = new AppDbContext())
{
var res2 = db.Goods.Select(m => new
{
Id = m.Id,
GoodsName = m.Name,
ManufacturerName = m.Manufacturer.Name,
}).ToList();
dataGridView1.DataSource = res2;
}
当你在这种情况下看,因为查询有2名场,必须声明为不同的别名他们并不等于实体中的DisplayNameAttribute
。有没有人知道一种方法来投影与实体中定义的DisplayNameAttribute
相同的输出列表?
看过DataGridView
源代码后,我已经看到数据源绑定到具有DisplayNameAttribute
属性的对象集合,它将在该属性的列标题中显示这些属性值。
所以,你只需要投影你的LINQ查询来查看定义属性的模型或实体。
例如,我有以下代码:
var listOfEntities = new List<CustomEntity>
{
new CustomEntity {Id = 1, Name = "Name1", Value = "Value1"},
new CustomEntity {Id = 2, Name = "Name2", Value = "Value2"},
new CustomEntity {Id = 3, Name = "Name3", Value = "Value3"},
new CustomEntity {Id = 4, Name = "Name4", Value = "Value4"},
};
dataGridView1.DataSource = listOfEntities;
public class CustomEntity
{
public int Id { get; set; }
[DisplayName("Custom name header")]
public string Name { get; set; }
[DisplayName("Custom name value")]
public string Value { get; set; }
}
如果你运行这个你会看到列标题是那些从DisplayNameAttribute
,没有属性的名称。
要投影查看模型,您可以使用AutoMapper自动映射字段。
UPDATE
您可以使用Expando
对象可能实现这一行为。 让我警告你,尽管你不能在你的上下文中调用.ToList()
之前使用它。因为这不会默认转换为有效的SQL查询。
using System.Reflection;
/*...*/
public static object ToDynamicDisplayName(object input)
{
var type = input.GetType();
dynamic dObject = new ExpandoObject();
var dDict = (IDictionary<string, object>)dObject;
foreach (var p in type.GetProperties())
{
var prop = type.GetProperty(p.Name);
var displayNameAttr = p.GetCustomAttribute<DisplayNameAttribute>(false);
if (prop == null || prop.GetIndexParameters().Length != 0) continue;
if (displayNameAttr != null)
{
dDict[displayNameAttr.DisplayName] = prop.GetValue(input, null);
}
else
dDict[p.Name] = prop.GetValue(input, null);
}
return dObject;
}
要使用它,尝试这样的:
var myDynamicCollection = DatabaseContext.Set<Manufacturer>().ToList().Select(m =>
ToDynamicDisplayName(m));
更新2
当然,我已经跑了代码,并成功建立。我的设置是使用.NET 4.6.2的VS2017。但是,我也为它创建了一个.Net小提琴,它可用here。
我的问题是_any的方式将DisplayName作为Linq查询的别名动态_,是你的答案做到这一点? –
我的回答说你不必这样做,你只需要定义你想要显示的属性的属性,它会自动工作。 –
是的,它的工作自动..但我想找到一种方法,把DisplayName作为别名Linq查询..如果你有一个建议,请告诉我。谢谢 –
这是否适合您的要求? https://stackoverflow.com/a/27275258/3296133 - 这篇文章中的方法需要一个类型,并创建一个数据表,然后您可以根据需要绑定到datagridview。 – DeeKayy90
@ DeeKayy90我想把别名放在Linq查询中......对此有建议吗? –
我认为这个问题更多,你为什么要在你的LINQ查询中使用别名?您的查询大概会进入数据库,因此您需要实际的“Name”字段才能转换为SQL。 我认为你应该寻找翻译你的查询结果,如果这是你的目标? – dougajmcdonald