这是泛型和C#';什么是动态数据类型?
因此,我面临的问题是,我们正在使用现有的ORM(它是一个旧的称为温柔的ORM)构建一个数据访问层,并考虑迁移到类似Fluent NHibernate的东西。在一些查询中,我们必须在现有设置中将自定义子句添加到SqlBuilder中,因此,例如,在检索某些person对象时,我们可能会添加如下子句:这是泛型和C#';什么是动态数据类型?,c#,generics,c#-4.0,dynamic,data-access-layer,C#,Generics,C# 4.0,Dynamic,Data Access Layer,因此,我面临的问题是,我们正在使用现有的ORM(它是一个旧的称为温柔的ORM)构建一个数据访问层,并考虑迁移到类似Fluent NHibernate的东西。在一些查询中,我们必须在现有设置中将自定义子句添加到SqlBuilder中,因此,例如,在检索某些person对象时,我们可能会添加如下子句: "PersonId in (SELECT PersonId from Orders where OrderValue > " + orderValue + " and OrderName = "
"PersonId in (SELECT PersonId from Orders where OrderValue > " + orderValue + " and OrderName = " + orderName
关键是参数直接添加到字符串中,而不是作为参数化查询添加,因此可以将其作为参数化查询添加,这就是我一直在研究的内容。我们所有的DAL都继承自一个基本的GentleDAL
,这是一个实际构造温和查询、添加子句和参数等的类。要在温和中添加参数化子句,您必须对SqlBuilder对象做两件事,您必须调用sb.AddConstraint(string子句)
来添加子句,然后,对于您必须调用的每个参数sb.AddParameter(字符串名称,类型)
,您可以从中构造SqlStatement
对象,只有在这之后,您才能在调用stmt.SetParameter(字符串名称,对象值)
的位置设置参数值
我表示这些参数/子句的方式是,我创建了一个名为GentleClauseCollection的类,该类包含子句和参数,并具有用于这两个方面的Add和Get方法。子句只是字符串,存储在列表的内部,参数存储在使用泛型的GentleParameter类中。GentleParameter的完整代码如下所示
public class GentleParameter<TParamType>
{
public string Name { get; private set; }
public TParamType Value { get; private set; }
public Type ParameterType {get { return typeof (TParamType); }}
public GentleParameter(string parameterName, TParamType parameterValue)
{
Name = parameterName;
Value = parameterValue;
}
}
公共类绅士参数
{
公共字符串名称{get;private set;}
公共TParamType值{get;private set;}
公共类型参数类型{get{return typeof(TParamType);}
公共GentleParameter(字符串参数名称,TParamType参数值)
{
名称=参数名称;
值=参数值;
}
}
据我所知,在.NET中没有一个集合允许我在同一集合中存储TpamType不同值的GentleParameter,但是可以使用DLR来完成。在我的GentelCollection类中,我将参数存储在一个列表中,并将该类中的参数作为IEnumerable获取。我的类中的Add方法只允许添加GentleParameter,因此我知道我的参数将始终具有名称、值和参数类型字段,我可以访问这些字段
我的问题是:如果我可以牺牲泛型并将参数类值属性改为“object”而不是T,那么我是否通过使用dynamic使事情变得过于复杂,这两种方法的优缺点是什么?如果所有使用动态对象的方法调用都将在运行时编译,那么有没有第三种方法可以做到这一点,我还没有想到,使用动态对象对性能的影响有多大
提前感谢您的帮助。由于
sb.SetParameter
不是泛型的,并等待对象
,我不会将GentleParameter
设置为泛型,因此我不会使用DLR。使用dynamic对我来说似乎并不太复杂。方法调用在运行时被解析,并被缓存。生成的调用可能平均慢10倍(我们说的是纳秒)。因此,这取决于你将如何使用它,如果它是有意义的
如果您总是将它用作type对象,那么您不需要使用type dynamic,这不会造成任何伤害
如果您希望能够访问属性,而不是应该使用dynamic,那么结果代码将比您所能做的任何事情都更干净
但即使使用dynamic,也不一定要动态调用属性本身,如果希望尽可能多地使用静态类型,可以使用dynamic resolve帮助器方法,该方法采用GentelParameter的通用形式,并在其中执行工作
...
private void HelperDoStuffWithGenericParam<T>(GentleParameter<T>param){
//Do stuff you have the static typing
}
。。。
私有void HelperDoStuffWithGenericParam(GentleParameterparam){
//你有静态打字吗
}
谢谢,我怀疑这是共识。+1关于静态类型助手方法的建议似乎很有趣。我将研究一下,看看我的代码是如何处理的。事实上,我认为这是一个很好的解决方案。我不清楚在我的情况下,这将如何工作,因为我有类似的问题。可数参数;foreach(parameters中的var参数){stmt.SetParameter(parameter.Name,parameter.Value);}我不知道如何将参数对象强制转换为GentleParameter,因为我直到运行时才知道它。在循环中调用HelperSetStatementParam(stmt,parameter)——void HelperSetStatementParam(SqlStatement stmt,GentleParameterparameter){stmt.SetParameter(parameter.Name,parameter.Value);}对帮助程序的调用在运行时解析。