我正在尝试从Linq查询结果中创建一个类实例。由于我必须为许多课程这样做,我正在尝试找到最合适的快捷方式。我想知道我是否可以将查询的“选择”部分缩短。
我的课程:
public class current_control_id_class
{
public string asset_class { get; set; }
public string region_code { get; set; }
public string instance_code { get; set; }
public int sdi_control_id { get; set; }
public int rows_loaded { get; set; }
}
我的作业功能:
foreach (var results in query)
{
foreach (PropertyInfo result in results.GetType().GetProperties())
{
string name = result.Name;
foreach (PropertyInfo info in used.GetType().GetProperties())
{
if (result.Name == info.Name)
{
Console.WriteLine("Result {0} matches class {1} and the value is {2}", result.Name, info.Name, result.GetValue(results,null));
}
}
}
}
我的查询(我知道这有效)
current_control_id_class used = new current_control_id_class();
var query =
from result in t_sdi_current_control_id.AsQueryable()
where result.asset_class == asset_class
&& result.region_code == region
&& result.instance_code == site
select new current_control_id_class() {
rows_loaded = result.rows_loaded,
sdi_control_id = result.sdi_control_id,
asset_class = result.asset_class,
hsbc_region_code = result.hsbc_region_code,
hsbc_instance_code = result.hsbc_instance_code
};
答案 0 :(得分:2)
您可以使用AutoMapper将t_sdi_current_control_id
的实例映射到current_control_id_class
的实例:
首先初始化映射:
Mapper.CreateMap<t_sdi_current_control_id, current_control_id_class>();
然后使用它:
var query =
from result in t_sdi_current_control_id.AsQueryable()
where result.asset_class == asset_class
&& result.region_code == region
&& result.instance_code == site
select Mapper.Map<current_control_id_class>(result);
答案 1 :(得分:0)
如果您不想使用第三方库,请参阅以下测试代码:
/// <summary>
/// Maps instances of <typeparam name="TSource"/> to new instances of
/// <typeparam name="TDestination"/> by copying across accessible public
/// instance properties whose names match.
/// </summary>
/// <remarks>
/// Internally uses a compiled Expression, so mapping should be quick at
/// the expense of <see cref="Mapper"/> initialisation.
/// </remarks>
public class Mapper<TSource, TDestination>
where TDestination : new()
{
readonly Func<TSource, TDestination> map;
public Mapper()
{
this.map = GenerateMapping();
}
static Func<TSource, TDestination> GenerateMapping()
{
var sourceProperties = GetPublicInstancePropertiesWithAccessors<TSource>(property => property.GetGetMethod());
var destinationProperties = GetPublicInstancePropertiesWithAccessors<TDestination>(property => property.GetSetMethod());
var source = Expression.Parameter(typeof(TSource));
var destination = Expression.Variable(typeof(TDestination));
var copyPropertyValues = from sourceProperty in sourceProperties
from destinationProperty in destinationProperties
where sourceProperty.Name.Equals(destinationProperty.Name, StringComparison.Ordinal)
select Expression.Assign(
Expression.Property(destination, destinationProperty),
Expression.Property(source, sourceProperty)
);
var variables = new[] { destination };
var assignNewDestinationInstance = Expression.Assign(destination, Expression.New(typeof(TDestination)));
var returnDestinationInstance = new Expression[] { destination };
var statements =
new[] { assignNewDestinationInstance }
.Concat(copyPropertyValues)
.Concat(returnDestinationInstance);
var body = Expression.Block(variables, statements);
var parameters = new[] { source };
var method = Expression.Lambda<Func<TSource, TDestination>>(body, parameters);
return method.Compile();
}
/// <summary>
/// Gets public instance properties of <typeparamref name="T"/> that
/// have accessible accessors defined by <paramref name="getAccessor"/>.
/// </summary>
static IEnumerable<PropertyInfo> GetPublicInstancePropertiesWithAccessors<T>(Func<PropertyInfo, MethodInfo> getAccessor)
{
var type = typeof(T);
var publicInstanceProperties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
return from property in publicInstanceProperties
let accessor = getAccessor(property)
where accessor != null
select property;
}
public TDestination Map(TSource source)
{
return map(source);
}
}
像这样使用:
//Keep this around so it gets re-used.
var mapper = new Mapper<t_sdi_current_control_id, current_control_id_class>();
var result = mapper.Map(value);