2014-10-10 40 views
0

我有一个名为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; } 
} 

这是我的问题就在DB管理员谁创建的存储过程,如果返回一个结果的“。导出“参数设置为true,并且如果”导出“参数设置为false,则返回0值。生成的代码似乎无法理解这一点。

如果我执行存储过程并将该值设置为false。我得到这个错误:

System.Data.Entity.Core.EntityCommandExecutionException: The data reader is incompatible with the specified 'CreatePrice_Result'. A member of the type, 'ActiveDate', does not have a corresponding column in the data reader with the same name.

我想以最简单的做法是要求数据库管理员修改存储过程返回无论设置出口值的结果,但这违背了这样的说法,因为点如果它设置为false,我不需要它。

有没有一种方法可以让我生成的代码来处理这两种情况,即处理两种返回类型。另外,我试图避免生成的代码中的手动更改,因为它被覆盖。

我试图改变返回类型为对象,并试图返回基于“出口”的说法

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

不同的结果,但我得到这个错误:

The type parameter 'System.Int32' in ExecuteFunction is incompatible with the type 'CreatePrice_Result' returned by the function.

感谢

+0

如果出口是假的,你不会在所有调用SP? – artm 2014-10-10 12:13:19

+0

@artm存储过程在两种情况下执行(它填充其他表),唯一的区别是如果导出为true,则返回该信息的结果集,如果它设置为false,则返回0 – mjroodt 2014-10-10 12:18:51

+0

我只看了一下但找不到关于返回多种返回类型的同一个SP的任何内容。不理想,但我能想到的是,如果导出是错误的,请尝试一下。其他解决方案是要求数据库管理员返回NULL NULL AS ActiveDate,NULL AS ActiveTime ...' – artm 2014-10-10 12:27:22

回答

1

我不相信这可以不诉诸ADO.NET对象。但是,您可以使用ObjectContext.Translate<TElement>方法将结果映射到实体对象,并可以选择跟踪实体集中的结果。下面的演示代码:

SQL存储过程:

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