2017-07-26 39 views
1

我有以下代碼,它使用EF獲取所有數據,然後嘗試將它們轉換爲Model,如下所示。LINQ to Entities無法識別該方法,並且此方法無法轉換爲商店表達式

var patients = allpatients.Select(p => CreatePatient(p)); 

    public Patient CreatePatient(PATIENT p) 
     { 
      Patient patient = new Patient(); 

      patient.FIRSTNAME = p.FIRSTNAME; 
      patient.MIDDLENAME = p.MIDDLENAME; 
      patient.SURNAME = p.SURNAME; 

      return patient; 
     } 

但收到這個錯誤

「LINQ實體無法識別方法‘Model.Patient CreatePatient(Repository.PATIENT)’方法,和這種方法不能被翻譯成表達商店。 「

回答

1

您可以只創建的LINQ新Patient對象選擇:

​​

或定義Patient構造函數接受另一個Patient對象,並使用所提供的Patient的值初始化自己:

public partial class Patient 
{ 
    public Patient(Patient p) 
    { 
     this.FIRSTNAME = p.FIRSTNAME; 
     this.MIDDLENAME = p.MIDDLENAME; 
     this.SURNAME = p.SURNAME; 
    } 
} 

然後在LINQ中選用:

var patients = allpatients.Select(p => new Patient(p)); 
+0

我可以,但我嘗試使用Model Factory,並將創建方法移動到另一個類。我試圖理解爲什麼錯誤。 – Simsons

+0

錯誤只是告訴'CreatePatient'方法不能被翻譯成SQL語句,你需要把它放在查詢語境之外。 –

1

這種說法不能直接翻譯成任何等價的SQL命令:

var patients = allpatients.Select(p => CreatePatient(p)); 

使用LINQ中的自定義擴展方法實體(EF數據上下文)常用的方法是先在模型上進行查詢(其能夠被翻譯成SQL語句),然後使用自定義擴展方法以外查詢上下文(這只是一個例子):

var patients = allpatients.Select(p => new Patient() 
{ 
    FIRSTNAME = p.FIRSTNAME, 
    MIDDLENAME = p.MIDDLENAME, 
    SURNAME = p.SURNAME 
}); 

foreach (Patient pt in patients) 
{ 
    // iterate through Patient collection 
    // use your custom method here 
} 

注意,相同的錯誤也會發生如果自定義方法變得LINQ查詢內部的new模型分配像本實施例中的一部分:

var patients = allpatients.Select(p => new Patient() 
{ 
    PATIENTID = ToInt32(p.PATIENTID), // ToInt32 is a custom extension method, e.g. converting string to int 
    FIRSTNAME = p.FIRSTNAME, 
    MIDDLENAME = p.MIDDLENAME, 
    SURNAME = p.SURNAME 
}); 

這是上述使用的正確的方法:

var patients = allpatients.Select(p => new Patient() 
{ 
    PATIENTID = p.PATIENTID, // leave the selected property as-is 
    FIRSTNAME = p.FIRSTNAME, 
    MIDDLENAME = p.MIDDLENAME, 
    SURNAME = p.SURNAME 
}); 

// another method content 
foreach (Patient pt in patients) 
{ 
    other.PATIENTID = ToInt32(pt.PATIENTID); 
} 

參考:

LINQ to Entities does not recognize the method

1

在這種情況下Select方法是extensi on方法爲IQuerable接口。此方法期望參數是表達式而不是函數。迭代集合時,表達式樹被LINQ to Entities(在本例中)解析,並轉換爲sql(用於LINQ to Entities)。和LINQ entite根本不知道如何將您的功能轉換爲SQL。

你可以做的是首先獲取數據,然後將你的functon應用到聚集中的每個元素。要做到這一點,你都可以ToArray的方法:

var patients = allpatients.ToArray().Select(p => CreatePatient(p)); 

或者遍歷集合:

foreach (Patient pt in allpatients) 
{ 
//do whatever you want here 
} 

這裏的缺點是,你加載所有列,所以如果你想獲取只有特定的人,你可以使用匿名對象:

var patients = allpatients.Select(p => new { FirstName = p.FIRSTNAME }).ToArray().Select(p => CreatePatient(p)); 

或爲dto對象創建一個類,例如,如果我想唯一的名字:

class PersonFirstNameDto { 
    public string FirstName { get; set; } 
} 

var patients = allpatients.Select(p => new PersonFirstNameDto { FirstName = p.FIRSTNAME }).ToArray().Select(p => CreatePatient(p)); 
相關問題