一般情况下List<T>中的T,都是已知的对象(即给定的对象)。所以使用.Select .FirstOrDefault查询起来很方便。网上也有很多这样的栗子。
我碰到的问题就是泛型对象中查询和设置值。网上没搜到查询方法。就自己写了个处理方式。
1. 在UtilConvert类中定义了2个方法:
public static class UtilConvert
{
/// <summary>
/// 获取对象字段的值
/// </summary>
/// <param name="obj"></param>
/// <param name="fieldID"></param>
/// <returns></returns>
public static string ObjGetFieldValue(this object obj,string fieldID)
{
Type type = obj.GetType();
PropertyInfo[] propertyInfos = type.GetProperties();
foreach (PropertyInfo item in propertyInfos)
{
if (item.Name.ToUpper() == fieldID.ToUpper())
return (item.GetValue(obj, null) == null ? "" : item.GetValue(obj, null)).ToString();
}
return "";
}
/// <summary>
/// 设置对象字段的值
/// </summary>
/// <param name="obj">Class对象</param>
/// <param name="fieldID">字段</param>
/// <param name="value">值</param>
/// <returns></returns>
public static bool ObjSetFieldValue(this object obj, string fieldID,string value)
{
Type type = obj.GetType();
PropertyInfo[] propertyInfos = type.GetProperties();
foreach (PropertyInfo item in propertyInfos)
{
if (item.Name.ToUpper() == fieldID.ToUpper())
{
item.SetValue(obj, string.IsNullOrEmpty(value) ? null : Convert.ChangeType(value, item.PropertyType), null);
return true;
}
}
return false;
}
}
2. 具体的实现方法:
#region 同步SFA数据
/// <summary>
/// 同步SFA数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <returns></returns>
private async Task<bool> AsyncSFADate<T>(string sql) where T : class, new()
{
try
{
SFARequestHelper sfaHelper = new SFARequestHelper();
//最后修改日期
string LastModifiedDate = "2022-05-01T07:37:50.000+0000";
var list_temp = await _dal.Query<T>("SEP_MSSQL_SFA_BK", "select * from " + typeof(T).Name);
if (list_temp != null && list_temp.Count > 0)
LastModifiedDate = list_temp.Max(o => o.ObjGetFieldValue("LastModifiedDate"));
if (!sql.ToUpper().Contains(" WHERE"))
sql = sql + " WHERE LastModifiedDate>=" + LastModifiedDate;
else
sql = sql + " and LastModifiedDate>=" + LastModifiedDate;
sql = sql + " order by LastModifiedDate ";
var ContractList = await sfaHelper.QueryDataList<T>(sql);
if (ContractList.Count > 0)
{
var IDs = ContractList.Select(o => o.ObjGetFieldValue("Id")).ToList();
_unitOfWork.BeginTran();
var list = await _dal.Query<T>("SEP_MSSQL_SFA_BK", "select * from " + typeof(T).Name + " where Id in (" + IDs.ListToString(true) + ")");
//var list = await _dal.Query<T>(o => IDs.Contains(o.ObjGetFieldValue("Id"))); //拉姆达不支持函数:ObjGetFieldValue
//数据同步到OA
List<T> insertList = new List<T>(); //新增
List<T> updateList = new List<T>(); //更新
foreach (var item in ContractList)
{
var info = list.FirstOrDefault(o => o.ObjGetFieldValue("Id").ToUpper() == item.ObjGetFieldValue("Id").Trim().ToUpper());
if (info == null)
{
//新增数据
info = new T();
ModelMapHelper.GetModelMerge<T, T>(item, info);
info.ObjSetFieldValue("AutoID", "0");
info.ObjSetFieldValue("IsDelete", ((int)AppEnum.YNStatus.No).ToString());
info.ObjSetFieldValue("CreateTime", DateTime.Now.ToString(AppConst.FormateDateTime));
insertList.Add(info);
}
else
{
//更新数据
if (item.ObjGetFieldValue("IsDelete") == ((int)AppEnum.YNStatus.No).ToString())
{
info.ObjSetFieldValue("AutoID", item.ObjGetFieldValue("AutoID"));
info.ObjSetFieldValue("IsDelete", item.ObjGetFieldValue("IsDelete"));
info.ObjSetFieldValue("CreateTime", item.ObjGetFieldValue("CreateTime"));
info.ObjSetFieldValue("UpdateTime", DateTime.Now.ToString(AppConst.FormateDateTime));
ModelMapHelper.GetModelMerge<T, T>(item, info);
updateList.Add(info);
}
}
}
if (insertList.Count > 0)
await _dal.Add<T>(insertList);
if (updateList.Count > 0)
await _dal.Update<T>(updateList);
_unitOfWork.CommitTran();
}
return true;
}
catch (Exception exp)
{
_logger.LogError(exp, "对象:" + typeof(T).Name + " Error:" + exp.Message);
}
_unitOfWork.RollbackTran();
return false;
}
#endregion
说明下,我是在Salesforce的同步中实现的,主要是把Salesforce中数据定时同步到下来。
SFARequestHelper是辅助类,这里不详讲了。
主要是这里使用方式:

注意拉姆达不支持。

本文介绍了如何在C#中处理泛型对象的字段查询和设置值,通过UtilConvert类的两个静态方法ObjGetFieldValue和ObjSetFieldValue实现对未知类型对象属性的访问。在实际应用中,例如在Salesforce数据同步场景中,这些方法被用于从数据库查询和更新数据。

1689

被折叠的 条评论
为什么被折叠?



