2017-07-15 65 views
-4

我有如下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

回答

1

看過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查詢..如果你有一個建議,請告訴我。謝謝 –