c# - 尝试使用表达式为可为空的 Guid 属性赋值
问题描述
大家好,我正在使用表达式树通过使用以下代码创建表达式来将值从源映射到目标
public static class PropertyMapper<TSource, TDest>
{
private static Expression<Func<TSource, Dictionary<string, MasterSection>, TDest>> _mappingExpression;
private static Func<TSource, Dictionary<string, MasterSection>, TDest> _mapper;
static PropertyMapper()
{
_mappingExpression = ProjectionMap();
_mapper = _mappingExpression.Compile();
}
public static Func<TSource, Dictionary<string, MasterSection>, TDest> Mapper => _mapper;
public static Expression<Func<TSource, Dictionary<string, MasterSection>, TDest>> ProjectionMap()
{
var sourceProperties = typeof(TSource).GetProperties().Where(p => p.CanRead);
var destProperties = typeof(TDest).GetProperties().Where(p => p.CanWrite);
var propertyMap =
from d in destProperties
join s in sourceProperties on new { d.Name, d.PropertyType } equals new { s.Name, s.PropertyType }
where d.Name != "SourceOfDataId"
select new { Source = s, Dest = d };
var itemParam = Expression.Parameter(typeof(TSource), "item");
var dictParam = Expression.Parameter(typeof(Dictionary<string, MasterSection>), "dict");
var memberBindings = propertyMap.Select(p => (MemberBinding)Expression.Bind(p.Dest, Expression.Property(itemParam, p.Source))).ToList();
var sourceOfDataProp = destProperties.FirstOrDefault(s => s.Name == "SourceOfDataId");
if (sourceOfDataProp != null)
{
// here i am setting one of the inner object(SourceOfData) ID to outer object nullable guid property (SourceOfDataId)
memberBindings.Add(Expression.Bind(sourceOfDataProp, Expression.Property(Expression.Property(itemParam, "SourceOfData"), "Id")));
}
var newExpression = Expression.New(typeof(TDest));
var memberInitExpression = Expression.MemberInit(newExpression, memberBindings);
var projection = Expression.Lambda<Func<TSource, Dictionary<string, MasterSection>, TDest>>(memberInitExpression, itemParam, dictParam);
return projection;
}
}
然后调用上面的方法,如下所示
AirflowsLab = sourceMechanicalData
.AirflowsLab
.Select(a => PropertyMapper<LibraryLabAirflow, LibraryLabAirflow>
.Mapper(a, masterSectionMappedLibrary)).ToList()
我在源实体和目标实体上有这些属性 SourceOfDataId、IsApproved,我试图将 IsApproved 设置为 true,并将 sourceOfDataId 设置为相应的值。
在此项目映射错误值已设置为 SourceOfDataId 而不是内部对象属性 Id 之后
实体 LibraryLabAirflow 看起来像这样
public class LibraryLabAirflow
{
[ForeignKey("SourceOfData")]
public Guid? SourceOfDataId { get; set; }
public virtual CodeStandardGuideline SourceOfData { get; set; }
public bool? IsApproved { get; set; }
}
我也尝试过下面的表达式绑定,但都没有奏效
尝试1:
var sourceOfDataPropertyBind = Expression.Bind(sourceOfDataProp, Expression.Property(Expression.Property(itemParam, "SourceOfData"),typeof(Guid?), "Id"));
尝试2:
var sourceOfDataPropertyBind = Expression.Bind(sourceOfDataProp, Expression.Property(Expression.Property(itemParam, typeof(Guid?), "SourceOfData"), "Id"));
并试图摆脱上面的这些表达
airflowLab => new LibraryLabAirflow
{
IsApproved = true,
SourceOfData = airflowLab.SourceOfData,
SourceOfDataId = airflowLab.SourceOfData.Id,
}
任何人都可以让我知道我在上面的代码中做错了什么,在此先感谢。
解决方案
Not quite sure why you need to assign airflowLab.SourceOfData.Id
to the explicit FK property SourceOfDataId
, since in the context of server side LINQ to Entities it should be the same as assigning directly airflowLab.SourceOfDataId
.
But let say for some reason you need that. Since the static type of the airflowLab.SourceOfData.Id
expression is non nullable Guid
(C# has no notion of implicit null propagation), the actual expression emitted by the C# compiler for
SourceOfDataId = airflowLab.SourceOfData.Id
would be
SourceOfDataId = (Guid?)airflowLab.SourceOfData.Id
Note the cast to nullable Guid
. In Expression
terms that maps to Expression.Convert
, so what you need is something like
Expression.Convert(
Expression.Property(Expression.Property(itemParam, "SourceOfData"), "Id"),
typeof(Guid?))
推荐阅读
- python - Python,检测是否重复进程正在运行
- multithreading - mod_wsgi 中的服务器发送事件 (SSE) 阻塞线程
- jquery - 无法关闭移动设备上的下拉菜单
- image - Scrapy不下载图像
- reactjs - 如何在 WebStorm 中调试 React 应用程序?
- c++ - 使用 static_cast 来实现动态多态性
- reactjs - 如何在使用反应钩子时初始化第三方库?
- android - 如果我想用语音和画布在屏幕上记录整个屏幕活动以通过触摸写任何东西,该研究什么?
- symfony - 解析自定义表单类型的 query_builder 中的选项
- r - 估计模拟数据上两个 x 值之间范围内的概率密度