我希望能够将FieldName作为字符串传递到更新表的Method中。我已经看过Linq.Expressions了,但是这似乎并没有显示我需要的有关字段Name和dataType的所有详细信息,并且我真的不想通过直接执行sql命令的现有字符串生成器解决方案。
public static Main(string[] args)
{
UpdateLicenceField(2284, "laststoragefullalert", DateTime.Now);
UpdateLicenceField(2284, "numberofalerts", int(tooMany);
UpdateLicenceField(2284, "lastalertmessage", "Oops");
}
public static void UpdateLicenceField(int LicenceID, string FieldName, object value)
{
using (myContext db = new MyContext())
{
Licence licence = db.Licence.Where(x => x.ID == LicenceID &&
x.Deleted == false).FirstOrDefault();
// so db.Licence has fields .laststoragefullalert .numberofalerts .lastalertmessage
// (in real life this has hundred of settings and we very often just want to update one)
// I'm tring to get a single Method that will act dynamically like the current ADO function that creates a SQL string and executes that.
// 1. check that the FieldName type is the same type as the object passed in value.
// 2. update that FieldName with value and Saves the Licence table.
}
}
答案 0 :(得分:0)
您可以使用https://github.com/StefH/System.Linq.Dynamic.Core中的“ System.Linq.Dynamic.Core”库并使用:
Licence licence = db.Licence.Where(FieldName + "==@0", fieldValue).FirstOrDefault();
或使用如下方法:
public Expression<Func<TEntity, bool>> GetPredicate(string methodName, string propertyName, string propertyValue)
{
var parameterExp = Expression.Parameter(typeof(TEntity), "type");
var propertyExp = Expression.Property(parameterExp, propertyName);
MethodInfo method = typeof(string).GetMethod(methodName, new[] { typeof(string) });
if (method == null)
{
var containsMethods = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).Where(m => m.Name == methodName);
foreach (var m in containsMethods)
{
if (m.GetParameters().Count() == 2)
{
method = m;
break;
}
}
}
var someValue = Expression.Constant(propertyValue, typeof(string));
var containsMethodExp = Expression.Call(propertyExp, method, someValue);
return Expression.Lambda<Func<TEntity, bool>>(containsMethodExp, parameterExp);
}
Licence licence = db.Licence.Where(GetPredicate("Contains", fieldName, fieldValue)).FirstOrDefault();
希望对您有帮助。
答案 1 :(得分:0)
非常感谢您的回复。我使用了Renan和Roberto的回复中的一些内容,我将它们组合在一起完成了工作。以这种方式进行更新显然并不理想,但这不是在自动化过程中使用类似代码的50或60个功能。仍然需要添加错误检查和验证,但这会大大减少我的代码库。
再次感谢格伦。
public static int Main(string[] args)
{
UpdateLicenceField(2284, "LastStorageFullAlert", DateTime.Now);
UpdateLicenceField(2284, "IsProcessing", true);
UpdateLicenceField(2284, "RegSource", "this is a string");
UpdateLicenceField(2284, "ProcessFilesDelay", 200);
return 1;
}
public static void UpdateLicenceField(int LicenceID, string Field, object Value)
{
using (BACCloudModel BACdb = new BACCloudModel())
{
Licence licence = BACdb.Licence.Where(x => x.ID == LicenceID && x.Deleted == false).FirstOrDefault();
if (licence != null)
{
var fieldvalue = licence.GetType().GetProperty(Field);
var ftype = fieldvalue.PropertyType;
var vtype = Value.GetType();
if (ftype == vtype)
{
object[] Values = { Value };
licence.GetType().GetProperty(Field).SetMethod.Invoke(licence, Values);
BACdb.SaveChanges();
}
}
}
}