2017-07-26 64 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)); 
相关问题