我有一个名为CreatePrice的存储过程,并已将其添加到edmx文件(数据库优先)我可以在模型浏览器中的函数导入下看到它,一切都很好。生成的函数如下所示:
public virtual ObjectResult<CreatePrice_Result> CreatePrice(string type, string code, string userName, Nullable<bool> export)
{
var typeParameter = type != null ?
new ObjectParameter("Type", type) :
new ObjectParameter("Type", typeof(string));
var codeParameter = code != null ?
new ObjectParameter("Code", code) :
new ObjectParameter("Code", typeof(string));
var userNameParameter = userName != null ?
new ObjectParameter("UserName", userName) :
new ObjectParameter("UserName", typeof(string));
var exportParameter = export.HasValue ?
new ObjectParameter("Export", export) :
new ObjectParameter("Export", typeof(bool));
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<CreatePrice_Result>("CreatePrice", typeParameter, codeParameter, userNameParameter, exportParameter);
}
返回类型如下:
public partial class CreatePrice_Result
{
public string ActiveDate { get; set; }
public string ActiveTime { get; set; }
public string InactiveDate { get; set; }
public string InactiveTime { get; set; }
}
这就是我的问题所在。如果“export”参数设置为true,则创建存储过程的DB Admin将返回结果集,如果“export”参数设置为false,则返回值0。生成的代码似乎不明白这一点。
如果我执行存储过程并将值设置为false。我收到这个错误:
System.Data.Entity.Core.EntityCommandExecutionException:数据读取器与指定的“CreatePrice_Result”不兼容。类型为“ActiveDate”的成员在数据读取器中没有相应的具有相同名称的列。
我想最简单的事情就是要求DB Admin修改存储过程以返回结果集而不管export的值如何但是这会破坏该参数的点,因为如果它被设置为false,我不会不需要它。
有没有办法让生成的代码能够处理这两种情况,即处理两种返回类型。此外,我试图避免生成的代码中的手动更改,因为它被覆盖。
我尝试将返回类型更改为object,并尝试根据“export”参数返回不同的结果
if (export == null || export == false)
{
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<int>("CreatePrice", typeParameter, codeParameter, userNameParameter, exportParameter);
}
else
{
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<CreatePrice_Result>("CreatePrice", typeParameter, codeParameter, userNameParameter, exportParameter);
}
但是我收到了这个错误:
ExecuteFunction中的类型参数'System.Int32'与函数返回的类型'CreatePrice_Result'不兼容。
由于
答案 0 :(得分:1)
我不相信如果不诉诸ADO.NET对象就可以做到。但是,您可以使用ObjectContext.Translate<TElement>
方法将结果映射到实体对象,并可选择跟踪实体集中的结果。下面的演示代码:
SQL sproc:
create proc dbo.FuzzyResultSet
(
@mode int
)
as
if( @mode = 1 )
begin
-- execute non-query
return @mode
end
else if( @mode = 2 )
begin
-- execute scalar
select @mode
end
else
begin
-- execute reader
select * from dbo.Watches
end
C#代码:
class Program
{
static void Main( string[] args )
{
using( var db = new DBFirst.EFMREntities() )
{
db.Database.Initialize( force: false );
try
{
db.Database.Connection.Open();
var objContext = ( db as IObjectContextAdapter ).ObjectContext;
// mode 0 returns a result set
var reader = GetCmd( db, 0 ).ExecuteReader();
var entityResults = objContext
.Translate<DBFirst.Watch>( reader,
// next two parms only if you want results in an entity set
"Watches", MergeOption.OverwriteChanges );
// mode 2 returns a scalar
var scalarResult = GetCmd( db, 2 ).ExecuteScalar();
// mode 1 does not return a result set
var cmd = GetCmd( db, 1 );
var nonQueryResult = cmd.ExecuteNonQuery();
var nonQueryReturnParm = cmd.Parameters[ "@RETURN_VALUE" ];
var nqrpValue = Convert.IsDBNull( nonQueryReturnParm.Value ) ? null : ( int? )nonQueryReturnParm.Value;
Console.WriteLine( "Entities returned: {0}", entityResults.Count() );
Console.WriteLine( "Scalar result: {0}", scalarResult );
Console.WriteLine( "Non-query results: {0} / {1}", nonQueryResult, nqrpValue );
}
finally
{
db.Database.Connection.Close();
}
}
Console.ReadLine();
}
private static DbCommand GetCmd( DbContext context, int value )
{
var cmd = context.Database.Connection.CreateCommand();
var inParm = cmd.CreateParameter();
inParm.ParameterName = "@mode";
inParm.Value = value;
var outParm = cmd.CreateParameter();
outParm.ParameterName = "@RETURN_VALUE";
outParm.Direction = ParameterDirection.ReturnValue;
cmd.CommandText = "dbo.FuzzyResultSet";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddRange( new []{ inParm, outParm } );
return cmd;
}
}