数据读取器与指定的实体框架不兼容

时间:2013-09-13 16:27:44

标签: c# .net tsql entity-framework-4

我有一个方法可以从sproc返回裸结果来填充选择菜单。当我想要裸结果时,我将bool getMin = true传递给sproc,当我想要完整记录时,我传递bool getMin = false。

这导致实体FrameWork错误“数据读取器与指定的不兼容”

错误中最相关的部分

  

{“Message”:“发生错误。”,“ExceptionMessage”:“数据读取器与指定的'CatalogModel.proc_GetFramingSystems_Result'不兼容。类型成员'FrameType'没有相应的数据读取器中具有相同名称的列。“,”ExceptionType“:”System.Data.EntityCommandExecutionException“,

显然错误告诉我,当数据读取器试图设置属性'FrameType'时,查询结果中没有。

现在我理解了这个错误,我想知道的是,我正在为了将这个sql sproc分成两个sprocs而进行goning,还是有解决方法?

我的功能

public static IEnumerable<IFramingSystem> GetFramingSystems(int brandID, string frameType, string glazeMethod, bool getMin)
{
    using (CatalogEntities db = new CatalogEntities())
    {
        return db.proc_GetFramingSystems(brandID, frameType, glazeMethod, getMin).ToList<IFramingSystem>();
    };
}

我的TSQL

ALTER proc [Catelog].[proc_GetFramingSystems]
@BrandID   INT,
@FrameType VARCHAR(26),
@GlazeMethod VARCHAR(7) ='Inside',
@getMin    BIT = 0
as
BEGIN
SET NOCOUNT ON;
IF @getMin =0
BEGIN
SELECT c.ID,c.Name,c.Descr,c.FrameType,c.isSubFrame,
       c.GlassThickness,c.GlassPosition,c.GlazingMethod,c.SillProfile
        from Catelog.Component c
WHERE c.MyType ='Frame' 
AND c.FrameType = @FrameType
AND c.GlazingMethod = @GlazeMethod
AND c.ID IN(
SELECT cp.ComponentID FROM Catelog.Part p JOIN
            Catelog.ComponentPart cp ON p.ID = cp.PartID
            WHERE p.BrandID = @BrandID
            )
            ORDER BY c.Name
END
ELSE
SELECT c.ID,c.Name,c.Descr
        from Catelog.Component c
WHERE c.MyType ='Frame' 
AND c.FrameType = @FrameType
AND c.GlazingMethod = @GlazeMethod
AND c.ID IN(
SELECT cp.ComponentID FROM Catelog.Part p JOIN
            Catelog.ComponentPart cp ON p.ID = cp.PartID
            WHERE p.BrandID = @BrandID
            )
            ORDER BY c.Name
SET NOCOUNT OFF;
END;

3 个答案:

答案 0 :(得分:13)

对我而言,似乎IF的两个分支都返回不同的数据,第一个分支返回9列,第二个分支返回三个。我相信EF无法反映后者的IFramingSystem。具体来说,列FrameType(以及其他5列)显然是缺失的:

 ...
 SELECT c.ID,c.Name,c.Descr    <- where are the remaining columns
    from Catelog.Component c
 ...

答案 1 :(得分:9)

我知道这是一个老帖子;但是,我想分享我今晚所学到的关于这一点的内容。我发现错误信息中“最相关的部分是陈述的”是这个。

db.proc_GetFramingSystems(brandID, frameType, glazeMethod, getMin).ToList<IFramingSystem>();

期望从存储过程返回一个列,其别名是'FrameType'。

当我创建一个POCO(普通的旧clr对象)类时,我遇到了更多程序员友好名称。而不是强烈输入的名称'email_address',我想要'EmailAddy'等等。我创建了一个映射类,在其他映射列中说明了这一点。

this.Property(t => t.EmailAddy).HasColumnName("email_address");

虽然这对于EF的其他部分是必要的,但是在执行db.SqlQuery时不会引用映射类。 所以,当下面的代码执行时

var a = new SqlParameter("@fshipno", shipno);
return _context.db.SqlQuery<EmailList>("exec spGetEmailAddy @fshipno", a).ToList();

它生成了相同的错误,除了代替'FrameType',它提到'EmailAddy'。 修复...我必须将存储过程中的'email_address'列别名为'EmailAddy',以使其将返回的数据集映射到我的POCO。

编辑:我发现只有当你的方法返回IEnumberable

时,这才有效
public IEnumberable<myPOCO> GetMyPoco()

如果您尝试返回单个POCO对象,则会收到相同的错误消息。

public myPOCO GetMyPoco()

答案 2 :(得分:1)

如果您要插入/删除/更新(这些被EF视为“非查询”),并且我们的代码可以使用

调用
MyDbContext.Database.ExecuteSqlCommand(insert into Table (Col1,Col2) values (1,2));

但是如果正在对原始SQL语句执行select查询,则使用

MyDbContext.DbSet<Table_name>.SqlQuery(select * from table_name).ToList();

MyDbContext.Database.SqlQuery(select * from table_name).ToList();

()

SqlQuery()函数,在EF中,由于奇怪的原因,抛出异常插入/删除/更新操作。 (引发的异常是“类型的成员,数据读取器中没有相应的列具有相同的名称。”)但是,如果您打开Sql Management Studio并检查条目,它实际上已执行了操作。

仅供参考http://www.entityframeworktutorial.net/EntityFramework4.3/raw-sql-query-in-entity-framework.aspx