2016-09-15 34 views
0

我想將字段連接到一個非字段是一個屬性相同的模型。LINQ到SQL,連接字段沒有新的動態類型創建

我有Person一個模型,該模型包括一個非字段屬性(NotMapped)稱爲FullName

public class Person 
{ 
    public int Id{get;set;} 
    public string firstname{get;set;} 
    public string lastname{get;set;} 

    [NotMapped] 
    public string FullName{get;set;} 
} 

現在我想選擇所有人員及其FullName

FullName = string.format("{0} {1}",firstname, lastname); 

我不由於沒有良好的性能和速度(對於約10K記錄),因此想要在每個人列表後分配完整姓名

除非你能爲我提供它與串連領域公式通用型號和表達動態lambda函數我不想使用新的選擇(動態類型),如下

var list = from pf in db.Persons 
      select new 
        { 
        Person = pf, 
        FullName = string.format("{0} {1}", pf.firstname, pf.lastname) 
        } 
List<Person> persons = new List<Person>(); 

// bad performance 
foreach(var item in list) 
{ 
    item.Person.FullName = item.FullName; 
    persons.Add(item); 
} 

例如:

public List<TModel> GetList<TModel>(Expression<Func<TModel, string>> cField = null,...) 
{ 
//all should done in database side with one query 
//select all records include FullName 
} 

我不想使用FullName.get

public string FullName 
{ 
    get { return string.format("{0} {1}", pf.firstname, pf.lastname); } 
} 

,因爲它是一樣的foreach方法,具有當您使用的datagridview該類糟糕的表現。

換句話說,我需要的是一個linq查詢,選擇所有人及其全名。

請注意,數據庫選擇後的任何賦值(特別是在與接口一起使用時)性能較差。

+1

你就不能使用它作爲'公共字符串全名{{返回的String.Format( 「{0} {1}」,名字,姓氏); }}'? – kiziu

+0

不!因爲fullname是一個示例,我需要的是超過5個字段的連接,因此處理FullName.get將花費寶貴的時間。它將綁定到datagridview – Hamid

回答

0

只需使用一些DTO它

public class PersonDto 
{ 
public int Id{get;set;} 
public string FirstName{get;set;} 
public string LastName{get;set;} 
public string FullName{get;set;} 
} 

,並選擇它像

db.Persons.Select(p => new PresonDto 
          { 
           Id = p.Id, 
           FirstName = p.firstname, 
           LastName = p.lastname, 
           FullName = p.firstname ?? "" + " " + p.lastname ?? "" 
          }); 

編輯

在情況下,如果你不希望使用DTOS,並希望更多的或少通用的方法你我沒有看到任何方式來填補sql查詢期間的對象的屬性。並選擇一些模型到新模型()重新分配所有字段不是好主意。

所以唯一可以提供的方式是使用一些容器來存儲您想要選擇的原始模型和其他字段。

public class ItemAdditionalPropertyContainer<TModel> 
{ 
    public TModel Item { get; set; } 
    public string PropertyValue { get; set; } 
} 

public static IQueryable<ItemAdditionalPropertyContainer<TModel>> GetItemsWithAdditionalProperty<TModel>(
    IQueryable<TModel> items, 
    Expression<Func<TModel, string>> additionalPropertySelector) 
{ 
    Expression<Func<TModel, ItemAdditionalPropertyContainer<TModel>>> expr = 
     item => new ItemAdditionalPropertyContainer<TModel> 
      { 
       Item = item, 
       PropertyValue = additionalPropertySelector.Compile()(item) 
      }; 
    return items.Select(expr.ExpandExpressions()); 
} 

但是你必須使用一些表達式擴展器,如你所見。 expr.ExpandExpressions()爲了讓LINQ以正確的方式進行編譯。

我用這個(git link)。這是nuget package。或者你可以自己實現它。

+0

您不需要空合併運算符,將'string's的加法運算符編譯爲可以處理null的'String.Concat'。 – kiziu

+0

nope。它將在通常的字符串連接中通過「+」進行編譯,如果其中一個值爲null,則整個字符串將爲空。 –

+0

正確,我跳過了用於創建對象的表達式也將轉換爲SQL的事實。 – kiziu

0

更改模型:

public class Person 
{ 
public int Id{get;set;} 
public string firstname{get;set;} 
public string lastname{get;set;} 

[NotMapped] 
public string FullName => firstname + " " + lastname; 
}