在EF 4.3中使用参数执行存储过程时,对象类型System.Collections.Generic.List中不存在映射

问题描述 投票:27回答:7

最近我一直在处理存储过程并遇到一个奇怪的问题。

首先,我能够通过以下方式从数据库成功调用存储过程:

IList <XXXViewModel> XXXList = _context.Database.SqlQuery(“spXXX”)。ToList();

但是当我需要传递参数时,它失败了:

var parameters = new List<SqlParameter>();
parameters.Add(new SqlParameter("param1", param1Value));
parameters.Add(new SqlParameter("param2", param2Value));
IList<XXXViewModel> XXXList =
_context.Database.SqlQuery<XXXViewModel>("spXXX @param1, @param2", parameters).ToList();

我得到了ff,错误:

对象类型System.Collections.Generic.List`1 [[System.Data.SqlClient.SqlParameter,System.Data,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]]中没有映射存在于已知的托管提供者本机类型。

请注意,我也尝试过:

_context.Database.ExecuteSqlCommand<EXEC XXXViewModel>("spXXX @param1, @param2", parameters).ToList();

但得到了相同的结果:-(。

我也尝试通过指定每个参数来调用:

IList<XXXResult> query = Context.Database.SqlQuery<XXXResult>("SP @paramA, @paramB, @paramC", new SqlParameter("paramA", "A"), new SqlParameter("paramB", "B"), new SqlParameter("paramC", "C")).ToList();

任何人有任何想法?

entity-framework entity-framework-4.1 ef-code-first
7个回答
32
投票

您需要将每个参数传递给方法(即您无法传递列表)

IList<XXXViewModel> XXXList =
     _context.Database.SqlQuery<XXXViewModel>("spXXX @param1, @param2", 
     new SqlParameter("param1", param1Value), 
     new SqlParameter("param2", param2Value)).ToList();

44
投票

如果有人遇到这个......

我创建了参数作为List,然后在SqlQuery调用中我用.ToArray()传递它。为我工作。这是以下修改后的代码......

var parameters = new List<object>(); 
parameters.Add(new SqlParameter("param1", param1Value)); 
parameters.Add(new SqlParameter("param2", param2Value)); 
IList<XXXViewModel> XXXList = 
_context.Database.SqlQuery<XXXViewModel>("spXXX @param1, @param2", parameters.ToArray()).ToList(); 

4
投票

这个问题的解决方案(在我的情况下是)

 var stuff = db.Database.SqlQuery<SomeEntityType>(query, parms);

其中query是一个插入参数的字符串,如@Name等.parms变量是一个SQLParameters列表。 SQL不喜欢通用列表....

SQL必须有一个SQLParameters数组和object [],而不是泛型类型列表。

var stuff = db.Database.SqlQuery<SomeEntityType>(query, parms.ToArray());

1
投票

在我的情况下,参数的SQL type和处理空值解决了这个问题。这也是同样的例外No mapping exists from object type System.RuntimeType to a known managed provider native type.

var parameter1 = new SqlParameter("parameter1", typeof(string));
var parameter2 = new SqlParameter("parameter2", typeof(string));
var parameter3 = new SqlParameter("parameter3", typeof(string));

parameter1.Value = string.IsNullOrEmpty(parameter1Value) ? (object)DBNull.Value : parameter1Value;
parameter2.Value = string.IsNullOrEmpty(parameter2Value) ? (object)DBNull.Value : parameter2Value;
parameter3.Value = string.IsNullOrEmpty(parameter3Value) ? (object)DBNull.Value : parameter3Value;

http://karim-medany.blogspot.ae/2014/02/no-mapping-exists-from-object-type.html


0
投票

没有说明SQL Server版本,但是Erland Sommarskog有一篇关于如何在SQL Server和.NET中使用表值参数的文章。

http://www.sommarskog.se/arrays-in-sql-2008.html

能够使用单个参数从客户端传递可变数量的参数。


0
投票

如果存储过程仅用于更新/插入,则也可以使用以下内容。

string cmd = Constants.StoredProcs.usp_AddRoles.ToString() + " @userId, @roleIdList";
int result = db.Database
                        .ExecuteSqlCommand
                        (
                           cmd,
                           new SqlParameter("@userId", userId),
                           new SqlParameter("@roleIdList", roleId)
                        );

-4
投票

您还可以使用string.Format将参数传递给存储过程

string command = string.Format("EXEC spXXX {0},{1}", param1Value, param2Value);
IList<XXXViewModel> XXXList = 
  _context.Database.SqlQuery<XXXViewModel>(command).ToList();
© www.soinside.com 2019 - 2024. All rights reserved.