C# 用于将简单实体属性自动映射到SqlParameters数组
我已经开始研究AutoMapper,有一个“数据驱动”的场景。。。我有根据我传递的一些“模式信息”从SqlDataReader填充实体属性的代码 下一步我想拿实体属性。。。然后根据我掌握的模式信息,从实体值创建一组SqlParameters 汽车制造商的完美工作。。。但我看到很多从对象图到对象图的扁平化,但没有简单的示例用于此任务。。。当我开始做这件事的时候,我有点被一些细微的差别绊倒了,但是我对我应该做什么有一个粗略的想法 我起草了以下文件。。。我试图使用类型转换器并提前注册它们,但当我执行实际的map.ForMember()操作时,它会抛出一个错误 “成员的自定义配置仅支持类型上的顶级单个成员。” 我尝试过一些变体,但没有成功 (1) 尝试了更简单的版本。。。 (2) 尝试使用ConstructUsing()机制,然后操作的目标实际上是SqlParameter。[[[Value]]]属性(很可能是AutoMapper思维方式中的“正确”方式对吗??) (3) 尝试预先建立目标列表,然后“查找”匹配参数-但设置其上的.Value仍然是等式中缺少的一部分 作为汽车制造商的新手,我期待着一些挑战,但我在这方面花了足够的时间,并没有发现任何明显的。。。似乎它应该是一个简单的框架用例。。。我一定错过了什么明显的C# 用于将简单实体属性自动映射到SqlParameters数组,c#,automapper,C#,Automapper,我已经开始研究AutoMapper,有一个“数据驱动”的场景。。。我有根据我传递的一些“模式信息”从SqlDataReader填充实体属性的代码 下一步我想拿实体属性。。。然后根据我掌握的模式信息,从实体值创建一组SqlParameters 汽车制造商的完美工作。。。但我看到很多从对象图到对象图的扁平化,但没有简单的示例用于此任务。。。当我开始做这件事的时候,我有点被一些细微的差别绊倒了,但是我对我应该做什么有一个粗略的想法 我起草了以下文件。。。我试图使用类型转换器并提前注册它们,但当我执行实
class Program
{
static void Main(string[] args)
{
// Drive it by some data... Say some mapping info we have from elsewhere...
var myMappingPairs = new List<MyMappingInfo>()
{
new MyMappingInfo() { PropertyName = "MyGuidProperty", ParameterName = "Param00" },
new MyMappingInfo() { PropertyName = "MyStringProperty", ParameterName = "Param01" },
new MyMappingInfo() { PropertyName = "MyInt16Property", ParameterName = "Param02" },
new MyMappingInfo() { PropertyName = "MyInt32Property", ParameterName = "Param03" },
new MyMappingInfo() { PropertyName = "MyInt64Property", ParameterName = "Param04" }
};
// We can try to register these, but the sytax isn't clear to me yet...
Mapper.CreateMap<Guid, SqlParameter>().ConvertUsing<GuidToSqlParameterConverter>();
Mapper.CreateMap<String, SqlParameter>().ConvertUsing<StringToSqlParameterConverter>();
Mapper.CreateMap<Int16, SqlParameter>().ConvertUsing<Int16ToSqlParameterConverter>();
Mapper.CreateMap<Int32, SqlParameter>().ConvertUsing<Int32ToSqlParameterConverter>();
Mapper.CreateMap<Int64, SqlParameter>().ConvertUsing<Int64ToSqlParameterConverter>();
// Next we'll build our mapping from the "pairings"...
var map = Mapper.CreateMap<MySourceEntity, List<SqlParameter>>();
foreach (var mappingPair in myMappingPairs)
{
map.ForMember
(
destination => destination,
options => options.ResolveUsing<PropertyNameResolver>().FromMember
(
mappingPair.PropertyName // <-- Data Driven Property Name...
)
);
}
// Create a test entity...
var entity = new MySourceEntity()
{
MyGuidProperty = Guid.NewGuid(),
MyStringProperty = "Hello AutoMapper",
MyInt16Property = Int16.MaxValue,
MyInt32Property = Int32.MaxValue,
MyInt64Property = Int64.MaxValue
};
// Map it...
var values = Mapper.Map<MySourceEntity, object[]>
(
entity
);
}
}
public class MySourceEntity
{
public string MyStringProperty { get; set; }
public DateTime? MyDateTimeProperty { get; set; }
public Byte? MyByteProperty { get; set; }
public Int16? MyInt16Property { get; set; }
public Int32? MyInt32Property { get; set; }
public Int64? MyInt64Property { get; set; }
public Guid? MyGuidProperty { get; set; }
public List<String> ThisShouldntGetMapped { get; set; }
public StringBuilder NorShouldThis { get; set; }
}
public class MyMappingInfo
{
public String PropertyName { get; set; }
public String ParameterName { get; set; }
public SqlDbType SqlDbType { get; set; }
}
public class GuidToSqlParameterConverter : AutoMapper.ITypeConverter<Guid, SqlParameter>
{
public SqlParameter Convert(ResolutionContext context)
{
if (context.IsSourceValueNull)
{
return new SqlParameter()
{
ParameterName = "GuidParam",
SqlDbType = SqlDbType.UniqueIdentifier,
Value = DBNull.Value
};
}
else
{
return new SqlParameter()
{
ParameterName = "GuidParam",
SqlDbType = SqlDbType.UniqueIdentifier,
Value = context.SourceValue
};
}
}
}
public class StringToSqlParameterConverter : AutoMapper.ITypeConverter<string, SqlParameter>
{
public SqlParameter Convert(ResolutionContext context)
{
if (context.IsSourceValueNull)
{
return new SqlParameter()
{
ParameterName = "StringParam",
SqlDbType = SqlDbType.NVarChar,
Value = DBNull.Value
};
}
else
{
return new SqlParameter()
{
ParameterName = "StringParam",
SqlDbType = SqlDbType.NVarChar,
Value = context.SourceValue
};
}
}
}
public class Int16ToSqlParameterConverter : AutoMapper.ITypeConverter<Int16, SqlParameter>
{
public SqlParameter Convert(ResolutionContext context)
{
if (context.IsSourceValueNull)
{
return new SqlParameter()
{
ParameterName = "Int16Param",
SqlDbType = SqlDbType.SmallInt,
Value = DBNull.Value
};
}
else
{
return new SqlParameter()
{
ParameterName = "Int16Param",
SqlDbType = SqlDbType.SmallInt,
Value = context.SourceValue
};
}
}
}
public class Int32ToSqlParameterConverter : AutoMapper.ITypeConverter<Int32, SqlParameter>
{
public SqlParameter Convert(ResolutionContext context)
{
if (context.IsSourceValueNull)
{
return new SqlParameter()
{
ParameterName = "Int32Param",
SqlDbType = SqlDbType.Int,
Value = DBNull.Value
};
}
else
{
return new SqlParameter()
{
ParameterName = "Int32Param",
SqlDbType = SqlDbType.Int,
Value = context.SourceValue
};
}
}
}
public class Int64ToSqlParameterConverter : AutoMapper.ITypeConverter<Int64, SqlParameter>
{
public SqlParameter Convert(ResolutionContext context)
{
if (context.IsSourceValueNull)
{
return new SqlParameter()
{
ParameterName = "Int64Param",
SqlDbType = SqlDbType.BigInt,
Value = DBNull.Value
};
}
else
{
return new SqlParameter()
{
ParameterName = "Int64Param",
SqlDbType = SqlDbType.BigInt,
Value = context.SourceValue
};
}
}
}
类程序
{
静态void Main(字符串[]参数)
{
//通过一些数据驱动它…说一些我们从别处得到的映射信息。。。
var myMappingPairs=新列表()
{
新建MyMappingInfo(){PropertyName=“MyGuidProperty”,ParameterName=“Param00”},
新建MyMappingInfo(){PropertyName=“MyStringProperty”,ParameterName=“Param01”},
新建MyMappingInfo(){PropertyName=“MyInt16Property”,ParameterName=“Param02”},
新建MyMappingInfo(){PropertyName=“MyInt32Property”,ParameterName=“Param03”},
新建MyMappingInfo(){PropertyName=“MyInt64Property”,ParameterName=“Param04”}
};
//我们可以尝试注册这些,但sytax对我来说还不清楚。。。
CreateMap().ConvertUsing();
CreateMap().ConvertUsing();
CreateMap().ConvertUsing();
CreateMap().ConvertUsing();
CreateMap().ConvertUsing();
//接下来,我们将从“配对”构建映射。。。
var map=Mapper.CreateMap();
foreach(myMappingPairs中的var mappingPair)
{
map.ForMember
(
目的地=>目的地,
options=>options.ResolveUsing().FromMember
(
mappingPair.PropertyName//p.Name,
p=>p.GetValue(obj,null)??DBNull.Value);
}
这就是对我来说使用AutoMapper的全部意义…我已经知道如何编写反射代码…我可以一直查看基于纯反射的库以获得一些额外的性能提升,但我认为AutoMapper可能是一笔两全其美的交易…顺便说一句-最后一个代码狙击手就是从这里开始的,所以…代码到哦,太长了。你能缩小范围吗?
static IDictionary<string, object> GetDictionaryFromObject(object obj)
{
if (obj == null) return new Dictionary<string, object>();
return obj.GetType().GetProperties()
.ToDictionary(p => p.Name,
p => p.GetValue(obj, null) ?? DBNull.Value);
}