用于从SQL Server读取数据的泛型函数
本文关键字:泛型 函数 数据 读取 SQL Server 用于 | 更新日期: 2023-09-27 17:59:42
假设我有两个类,它们看起来像这样。
class Foo1
{
public String P1 { get; set; }
public String P2 { get; set; }
}
class Foo2
{
public String P3 { get; set; }
public String P4 { get; set; }
}
P1、P2、P3和P4没有任何关联。与Foo1和Foo2相同。它们代表着完全不同的物体。
我有两个数据库表,它们有一个Foo1和Foo2对象列表。我必须创建一个List<Foo1>
和List<Foo2>
返回Foo1和Foo2的存储过程的输入是不同的。
这是我的问题——我想创建一个通用函数,该函数将连接到数据库,并根据我的意愿提取Foo1或Foo2列表
最初我想到了类似的东西
internal static SqlDataReader GetData(String Proc,NameValueCollection InputParams,SqlConnection conn, ref String Err)
{
using (SqlCommand cmd = conn.CreateCommand())
{
try
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = Proc;
conn.Open();
SqlCommandBuilder.DeriveParameters(cmd);
foreach (SqlParameter p in cmd.Parameters)
{
if (p.Direction == ParameterDirection.Input)
{
if (InputParams[p.ParameterName.ToLower().Substring(1)] != String.Empty)
{
p.Value = InputParams[p.ParameterName.ToLower().Substring(1)];
p.DbType = DbType.AnsiString;
}
else
{
Err += "<argumentnotfound>" + p.ParameterName + "</argumentnotfound>";
}
}
else p.Value = DBNull.Value;
}
return cmd.ExecuteReader();
}
catch (Exception e)
{
return null;
}
}
}
我不喜欢返回SqlDataReader或在此函数之外创建和关闭SqlConnection的想法。
理想情况下,我希望在该函数中遍历"reader"对象,但返回List<Foo1>
或List<Foo2>
。我能想到的一个解决方案是
internal static List<Object> GetData(NameValueCollection InputParams, ref String Err, String ClassName, String Proc)
{
List<Object> [] objectlist = new List<Object>();
using (SqlConnection conn = getConnection())
{
using (SqlCommand cmd = conn.CreateCommand())
{
try
{
/*
~~ Same as before
*/
SqlDataReader reader = cmd.ExecuteReader();
while(reader.Read())
{
if(ClassName == "Foo1")
{
Foo1 f = new Foo1();
f.P1 = reader["p1"].ToString();
objectList.Add(f1);
}
else if(ClassName == "Foo2")
{
/* Create and initialize Foo2 object*/
objectList.Add(f2);
}
}
return objectList;
}
catch (Exception e)
{
}
finally
{
conn.Close();
}
}
}
return null;
}
有更好/优雅的方法吗?
编辑
我忘了提到这一点——我的最终目标是为Javascript中的AJAX调用创建JSON。我的计划是迭代Foo1和Foo2对象列表,为每个请求创建Json数据。
我认为我可以在存储过程中创建JSON,并将其作为varchar(max)返回,并使用JSON2.js在客户端创建JSON对象我在这里看到的缺点是varchar的限制为8000个字符
我认为你不会花太多钱来尝试将其通用化。在创建Foo1
和Foo2
的过程之间唯一真正共同的部分是创建/关闭Connection
和DataReader
。它们将具有不同的SQL命令以及DataReader
和类之间的不同映射。
我的建议是,要么使用像NHibernate或Entity Framework这样已经抽象掉数据库垃圾的库,要么抽象掉这些部分,并让工厂从DataReader
创建Foo1
和Foo2
实例。否则,您将使用一堆开关,这些开关会根据您试图创建的对象的类型(这是您要走的路)更改代码,或者使用反射自动将属性映射到数据库列。
不幸的是,我不是专家,但我想我明白你想做的。我的建议(尽管可能不是最好的)是创建一个数据类型的枚举,然后在泛型函数中搜索提交,然后你可以对输入的字符串使用表名。
我使用类似的方法来存储这种性质的信息,它看起来像这样。。。
功能:
public UInt32 getKeyCode(string Key)
{
Constants.KeyboardControls keynum;
if (Enum.TryParse<Constants.KeyboardControls>(Key, true, out keynum))
{
return (UInt32)(keynum);
}
else
{
return new UInt32();
}
}
枚举:
public enum KeyboardControls : uint
{
F1 = 0x70,
F2 = 0x71,
F3 = 0x72,
F4 = 0x73,
F5 = 0x74,
F6 = 0x75,
F7 = 0x76,
F8 = 0x77,
F9 = 0x78,
F10 = 0x79,
F11 = 0x7A,
F12 = 0x7B,
left = 0x25,
up = 0x26,
right = 0x27,
down = 0x28
}
我希望这至少有一点帮助,你可以在枚举中列出任何对象,只需将它所说的uint更改为你的对象类型,左侧几乎是字符串。