在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相同的输出列表?

+1

这是否适合您的要求? https://stackoverflow.com/a/27275258/3296133 - 这篇文章中的方法需要一个类型,并创建一个数据表,然后您可以根据需要绑定到datagridview。 – DeeKayy90

+0

@ DeeKayy90我想把别名放在Linq查询中......对此有建议吗? –

+2

我认为这个问题更多,你为什么要在你的LINQ查询中使用别名?您的查询大概会进入数据库,因此您需要实际的“Name”字段才能转换为SQL。 我认为你应该寻找翻译你的查询结果,如果这是你的目标? – dougajmcdonald

看过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

+0

我的问题是_any的方式将DisplayName作为Linq查询的别名动态_,是你的答案做到这一点? –

+0

我的回答说你不必这样做,你只需要定义你想要显示的属性的属性,它会自动工作。 –

+0

是的,它的工作自动..但我想找到一种方法,把DisplayName作为别名Linq查询..如果你有一个建议,请告诉我。谢谢 –