2017-03-03 66 views
0

目前我正在清理我承包进行维护的应用程序的后端上的一些代码。我遇到了一个方法,通过Oracle Data Reader对数据库进行调用。在检查了SQL之后,我意识到没有必要打开Oracle数据读取器的调用来查看加载的对象是如何在我们的实体框架的上下文中。我改变了代码来遵循实体模型的使用。以下是我所做的更改。来自SQL查询的错误

原始代码

var POCs = new List<TBLPOC>(); 

Context.Database.Connection.Open(); 
var cmd = (OracleCommand)Context.Database.Connection.CreateCommand(); 
OracleDataReader reader; 
var SQL = string.Empty; 
if (IsAssociate == 0) 
    SQL = @"SELECT tblPOC.cntPOC,INITCAP(strLastName),INITCAP(strFirstName) 
      FROM tblPOC,tblParcelToPOC 
      WHERE tblParcelToPOC.cntPOC = tblPOC.cntPOC AND 
       tblParcelToPOC.cntAsOf = 0 AND 
       tblParcelToPOC.cntParcel = " + cntParcel + " ORDER BY INITCAP(strLastName)"; 
else 
    SQL = @"SELECT cntPOC,INITCAP(strLastName),INITCAP(strFirstName) 
      FROM tblPOC 
      WHERE tblPOC.cntPOC NOT IN (SELECT cntPOC 
             FROM tblParcelToPOC 
             WHERE cntParcel = " + cntParcel + @" 
              AND cntAsOf = 0) 
       AND tblPOC.ysnActive = 1 ORDER BY INITCAP(strLastName)"; 
cmd.CommandText = SQL; 
cmd.CommandType = CommandType.Text; 
using (reader = cmd.ExecuteReader()) 
{ 
    while (reader.Read()) 
    { 
     POCs.Add(new TBLPOC { CNTPOC = (decimal)reader[0], 
           STRLASTNAME = reader[1].ToString(), 
           STRFIRSTNAME = reader[2].ToString() }); 
    } 
} 
Context.Database.Connection.Close(); 
return POCs; 

替换代码

var sql = string.Empty; 
if (IsAssociate == 0) 
    sql = string.Format(@"SELECT tblPOC.cntPOC,INITCAP(strLastName),INITCAP(strFirstName) 
          FROM tblPOC,tblParcelToPOC 
          WHERE tblParcelToPOC.cntPOC = tblPOC.cntPOC 
           AND tblParcelToPOC.cntAsOf = 0 
           AND tblParcelToPOC.cntParcel = {0} 
          ORDER BY INITCAP(strLastName)", 
          cntParcel); 
else 
    sql = string.Format(@"SELECT cntPOC,INITCAP(strLastName), INITCAP(strFirstName) 
          FROM tblPOC 
          WHERE tblPOC.cntPOC NOT IN (SELECT cntPOC 
                 FROM tblParcelToPOC 
                 WHERE cntParcel = {0} 
                 AND cntAsOf = 0) 
           AND tblPOC.ysnActive = 1 
          ORDER BY INITCAP(strLastName)", 
          cntParcel); 

return Context.Database.SqlQuery<TBLPOC>(sql, "0").ToList<TBLPOC>(); 

我有现在的问题是在执行替换代码时,我得到以下错误:

的数据读取器与指定的“TBLPOC”不兼容。 “CNTPOCORGANIZATION”类型的成员在数据读取器中没有相应的列,名称相同。

字段cntPOCOrganization确实存在于tblPOC以及TBLPOC实体中。 cntPOCOrganization是一个可以为空的小数(不要问为什么小数,我自己不明白为什么之前的承包商使用小数而不是整数作为标识符......)。但是,在过去的代码和较新的代码中,不需要填写该字段。我很困惑为什么它在这个特定领域出错。

如果有人有任何见解,我会真正感激它。谢谢。

编辑:所以想到它多一点,做一些研究,我想我知道这是什么问题。在TBLPOC的实体模型中,cntPOCOrganization字段为空,但是,存在一个与此实体模型关联的称为TBLPOCORGANIZATION的对象。我在想它是否试图填补它。它本身也有cnt​​POCOrganization,我猜测它可能是试图填充本身,并且是导致问题的原因。

这也许可能是以前的承包商编写Oracle Command与通过Entity Framework运行它的原因。我会暂时恢复(在截止日期之前,真的不想打得太久)。谢谢!

+0

这听起来像读者没有框架需要填写的对象的所有领域。 – JuanR

+0

就像我之前提到的,我认为问题是与此实体关联的子实体。读者注意到它们,并且由于子对象中存在非空值,所以会引发错误。这也可能是因为对象也基于查询丢失了几乎所有的字段(查询只抽取三个字段,实际上更多的是10-15个字段)。 – IyaTaisho

+0

是的,我认为你是在正确的轨道上。您要求EF为您查询查询结果,因此期望读者拥有一切。我很好奇,是字段“cntPOCOrganization”的一个对象还是一个集合?这是它的一个对象,那么它必须是数据库上的1对1关系。 – JuanR

回答

0

当您的EF实体模型与查询结果不匹配时,会发出此错误。如果你发布你的实体模型,你试图获取它,SQL可以修复。一般来说,你需要使用:

sql = string.Format(@"SELECT tblPOC.cntPOC AS <your_EF_model_property_name_here>,INITCAP(strLastName) AS <your_EF_model_property_name_here>,INITCAP(strFirstName) AS <your_EF_model_property_name_here> 
         FROM tblPOC,tblParcelToPOC 
         WHERE tblParcelToPOC.cntPOC = tblPOC.cntPOC 
          AND tblParcelToPOC.cntAsOf = 0 
          AND tblParcelToPOC.cntParcel = {0} 
         ORDER BY INITCAP(strLastName)", 
         cntParcel); 
+0

我发布后更正了名字,因为我认为是同一件事。但是,我仍然遇到同样的错误。 – IyaTaisho