3

简短的:

我们有一个接受参数的 C# 方法。

在那个方法里面我们需要添加Sql参数(根据方法参数)。

它实际上看起来像这样:http: //i.stack.imgur.com/QP1y2.jpg(放大) 在此处输入图像描述

请注意

我可以编写一个包含所有方法参数的类。但是,我将不得不为每个 SP 创建一个类容器(我们有很多)。

好的,让我们继续。

我在想自己:“为什么我要手动插入每个参数- 如果我已经在方法参数中拥有它的 : name, type, value?我不想这样做,也许反射会为我做这件事”(让我们暂时离开的转换int <->DbType.Int32

但是我遇到了一个问题。使用反射无法读取值。

但是,我确实设法通过反射通过 hack 读取值。

1)我做了这个例子:(模拟真实场景)

public static void MyMethod(int AddressId, string countryId, DateTime dt) //these are the arguments which need to be attached later
{

 MethodBase mi = MethodInfo.GetCurrentMethod();
 var hack = new {AddressId, countryId, dt}; //this is the HACK


var lstArguments = mi.GetParameters()  //get the parameter  name and types
                    .Select(p => new {
                                 name = p.Name  , type=p.GetType().Name
                                 }).ToList();


List < dynamic > lstParamValues= new List < dynamic > ();

foreach(PropertyInfo pi in hack.GetType().GetProperties())  //get the value(!!!) of each param 
{

       lstParamValues.Add(pi.GetValue(hack, null));
}


  dynamic dyn= myDBInstance; // get dynamic reference to the DB class instance ( 

for(int i = 0; i < lstArguments .Count; i++) //dynamically Invoke the method with param name+value.
{
    dyn.AddInParameter(lstArguments [i].name, ((lstParamValues[i] is int) ? DbType.Int32 : DbType.String), lstParamValues[i]);
}

}

还有DB类模拟AddInParameter看我是否得到值)

class myDB
{
    public void AddInParameter(string name, DbType dbt, object val)
    {
        Console.WriteLine("name=" + name + "    " + "DbType=" + dbt + "    " + "object val=" + val);
    }
}

它正在工作:

我使用以下方法执行了该方法:

MyMethod(1, "2", DateTime.Now);

输出是:

name=AddressId    DbType=Int32    object val=1
name=countryId    DbType=String    object val=2
name=dt    DbType=String    object val=05/02/2013 19:09:32

一切都好。

C# 问题

我怎样才能克服这个黑客:

 var hack = new {AddressId, countryId, dt};  //  the method arguments names

在我的示例中,我将其编写为硬编码。

反射方法GetValue仅因为这条线而起作用。

我可以做些什么来在运行时将方法参数名称添加为属性,这样我就可以做到:

 foreach(PropertyInfo pi in SOMETHING.GetType().GetProperties()) 
   {
   }

请将此问题视为 ac# 问题而不是 ORM 问题。

另外,如果你想玩运行示例代码(只需粘贴到控制台项目中):http: //jsbin.com/azicut/1/edit

4

3 回答 3

0

这是否提供了一些缓解?

执行一次(在 DAL ctor 中):

SqlParameter sqlCmdFTSindexWordOnceParam = sqlCmdFTSindexWordOnce.Parameters.Add("@sID", SqlDbType.Int);
sqlCmdFTSindexWordOnceParam.Direction = ParameterDirection.Input;
SqlParameter sqlCmdFTSindexWordOnceParam2 = sqlCmdFTSindexWordOnce.Parameters.Add("@sIDpar", SqlDbType.Int);
sqlCmdFTSindexWordOnceParam2.Direction = ParameterDirection.Input;

然后在通话中:

sqlCmdFTSindexWordOnceParam.Value = wdc.sID;
sqlCmdFTSindexWordOnceParam2.Value = wdc.sIDpar;                                    
sqlCmdFTSindexWordOnce.BeginExecuteNonQuery(callbackFTSindexWordOnce, sqlCmdFTSindexWordOnce);

比为每个调用添加参数更好的性能。

于 2013-02-05T17:49:08.913 回答
0

AddWithValue至少可以让您免于编写类型名称。

 command.Parameters.AddWithValue("@demographics", demoXml);

但是你真的不应该将那么多参数传递给函数。一个简单的DTO类可以使您的代码更具可读性。如果我没记错的话,您正在寻找类似于 pyhton 的东西locals需要类似于 python 中的 locals的东西),它为您提供函数的局部变量作为键值对,据我所知,您不能在 c# 中执行此操作。

或者您简单地不传递所有变量,您只需传递 aDictionary<string,object>并将键值添加到 SqlParameter

于 2013-02-05T17:55:25.987 回答
-3

我不熟悉 c# 和 .net 的工作原理,但如果这是 java,我会说:

将当前参数存储到数组列表或映射中

你可以有 3 个数组列表,一个用于进入 addInParameters 方法调用的每个参数,或者一个包含所有值的映射(类型参数需要像现在一样有一些重复)

在插入/更新方法中使用数组列表作为唯一参数 使用 for 循环,以便 AddInParameter 调用只写入一次,参数类似于 (array1[0], array2[0], array3[0]) 而不是比实际值。

在 php 中你可以使用关联数组,.net 有关联数组吗?

于 2013-02-05T17:38:31.190 回答