LINQ to Entities无法识别该方法,并且此方法无法转换为存储表达式

时间:2017-07-26 07:06:31

标签: c# .net entity-framework asp.net-web-api

我有以下代码,使用EF获取所有数据,然后尝试将它们转换为模型,如下所示。

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 to Entities无法识别方法'Model.Patient CreatePatient(Repository.PATIENT)'方法,并且此方法无法转换为商店表达式。”

3 个答案:

答案 0 :(得分:2)

您可以在LINQ select中创建新的Patient对象:

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

或者定义一个接受另一个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));

答案 1 :(得分:2)

此语句不能直接转换为任何等效的SQL命令:

PagerSnapHelper pagerSnapHelper = new PagerSnapHelper();
pagerSnapHelper.attachToRecyclerView(recyclerView);

在LINQ to Entities(EF数据上下文)中使用自定义扩展方法的常用方法是首先对模型执行查询(可以将其翻译成SQL语句),然后使用自定义扩展方法 查询上下文(这只是一个例子):

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

请注意,如果自定义方法成为LINQ查询中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 } 模型分配的一部分,则会发生相同的错误 ,如下例所示:

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
});

参考:

LINQ to Entities does not recognize the method

答案 2 :(得分:1)

在这种情况下,Select方法是IQuerable接口的扩展方法。此方法要求参数是表达式而不是函数。迭代集合时,表达式树由LINQ to Entities解析(在本例中),并转换为sql(对于LINQ to Entities)。 LINQ to entites根本不知道如何将你的函数转换为sql。

您可以先获取数据,然后将您的功能应用于集合中的每个元素。要做到这一点,你可以使用所有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));