Entity Framework - 如何使用字符串变量引用列名
Entity Framework - How to reference a column name using a string variable
我有一个名为 "Account." 的 table 帐户有 3 列:id、acct_name、is_privileged。
当我写类似 "account." 的内容时,visual studio 为我提供了一个我可以使用的 attributes/methods 列表。因此,我可以选择使用 account.id
、account.acct_name
和 account.is_privileged
。
但是,我想动态更改特定列的值,而无需输入我的列名称。我正在以字符串变量的形式动态获取列名。有可能实现吗?如果可以,怎么做?
我的代码如下:
set_col_name = rowRule.Cells["setcolumnnameDataGridViewTextBoxColumn"].Value.ToString();
set_col_value = rowRule.Cells["setcolumnvalueDataGridViewTextBoxColumn"].Value.ToString();
foreach (DataGridViewRow rowAcc in dgvAccount.Rows)
{
if (isComparable(rowAcc.Cells[col_name].Value.ToString(), comp_operator, col_value))
{
account.id = (int)rowAcc.Cells["idDataGridViewTextBoxColumn2"].Value;
using (ae = new AccountEntities())
{
var temp = ae.Accounts.SingleOrDefault(a => a.id == account.id);
temp.is_privileged = set_col_value; //learn how to do this dynamically
ae.SaveChanges();
}
}
}
在我做的事情 temp.is_privileged 中,我想实现类似 temp."set_col_name" = set_col_value;
的目标
在这种情况下,我不想直接将列名称指定为 "is_privileged",而是想传递一个字符串来指定它。
谢谢。
你需要对此进行一些反思。例如
public static void CopyValues<T>(T obj1, T obj2)
{
var type = typeof(T);
foreach (var prop in type.GetProperties())
{
prop.SetValue(obj1, prop.GetValue(obj2));
}
}
并像这样使用上面的函数:
var source = new Accounts(){is_privileged = false};
var destiny = new Accounts();
CopyValues(source, destiny);
这取决于你在寻找什么,但关键是要使用REFLECTION!
如果我正确理解你的问题陈述,你希望这样的事情起作用:
Account temp = // with temp coming from a library such as EntityFramework
temp.SetValue(set_col_name, set_col_value);
这很容易通过纯反射或 Linq 表达式树(我选择的)实现:
static class Ext
{
public static void Set<T, TProperty>(this T instance, string propertyName, TProperty value)
{
var instanceExpression = Expression.Parameter(typeof(T), "p");
var propertyGetterExpression = Expression.PropertyOrField(instanceExpression, propertyName);
//generate setter
var newValueExpression = Expression.Parameter(typeof(TProperty), "value");
var assignmentExpression = Expression.Assign(propertyGetterExpression, newValueExpression);
var lambdaExpression = Expression.Lambda<Action<T, TProperty>>(assignmentExpression, instanceExpression, newValueExpression);
var setter = lambdaExpression.Compile();// the generated lambda will look like so: (p, value) => p.{your_property_name} = value;
setter(instance, value);
}
}
与纯反射相比,此方法的一个优点是您可以构建一次 setter 委托并在稍后阶段多次调用它(我将把它留给您进行实验)
有了上面的内容,希望你应该能够做这样的事情:
var set_col_name = "is_privileged";
var set_col_value = true;
using (ae = new AccountEntities())
{
var temp = ae.Accounts.SingleOrDefault(a => a.id == account.id);
temp.Set(set_col_name, set_col_value);
temp.Set("acct_name", "test");
ae.SaveChanges();
}
我有一个名为 "Account." 的 table 帐户有 3 列:id、acct_name、is_privileged。
当我写类似 "account." 的内容时,visual studio 为我提供了一个我可以使用的 attributes/methods 列表。因此,我可以选择使用 account.id
、account.acct_name
和 account.is_privileged
。
但是,我想动态更改特定列的值,而无需输入我的列名称。我正在以字符串变量的形式动态获取列名。有可能实现吗?如果可以,怎么做?
我的代码如下:
set_col_name = rowRule.Cells["setcolumnnameDataGridViewTextBoxColumn"].Value.ToString();
set_col_value = rowRule.Cells["setcolumnvalueDataGridViewTextBoxColumn"].Value.ToString();
foreach (DataGridViewRow rowAcc in dgvAccount.Rows)
{
if (isComparable(rowAcc.Cells[col_name].Value.ToString(), comp_operator, col_value))
{
account.id = (int)rowAcc.Cells["idDataGridViewTextBoxColumn2"].Value;
using (ae = new AccountEntities())
{
var temp = ae.Accounts.SingleOrDefault(a => a.id == account.id);
temp.is_privileged = set_col_value; //learn how to do this dynamically
ae.SaveChanges();
}
}
}
在我做的事情 temp.is_privileged 中,我想实现类似 temp."set_col_name" = set_col_value;
的目标
在这种情况下,我不想直接将列名称指定为 "is_privileged",而是想传递一个字符串来指定它。
谢谢。
你需要对此进行一些反思。例如
public static void CopyValues<T>(T obj1, T obj2)
{
var type = typeof(T);
foreach (var prop in type.GetProperties())
{
prop.SetValue(obj1, prop.GetValue(obj2));
}
}
并像这样使用上面的函数:
var source = new Accounts(){is_privileged = false};
var destiny = new Accounts();
CopyValues(source, destiny);
这取决于你在寻找什么,但关键是要使用REFLECTION!
如果我正确理解你的问题陈述,你希望这样的事情起作用:
Account temp = // with temp coming from a library such as EntityFramework
temp.SetValue(set_col_name, set_col_value);
这很容易通过纯反射或 Linq 表达式树(我选择的)实现:
static class Ext
{
public static void Set<T, TProperty>(this T instance, string propertyName, TProperty value)
{
var instanceExpression = Expression.Parameter(typeof(T), "p");
var propertyGetterExpression = Expression.PropertyOrField(instanceExpression, propertyName);
//generate setter
var newValueExpression = Expression.Parameter(typeof(TProperty), "value");
var assignmentExpression = Expression.Assign(propertyGetterExpression, newValueExpression);
var lambdaExpression = Expression.Lambda<Action<T, TProperty>>(assignmentExpression, instanceExpression, newValueExpression);
var setter = lambdaExpression.Compile();// the generated lambda will look like so: (p, value) => p.{your_property_name} = value;
setter(instance, value);
}
}
与纯反射相比,此方法的一个优点是您可以构建一次 setter 委托并在稍后阶段多次调用它(我将把它留给您进行实验)
有了上面的内容,希望你应该能够做这样的事情:
var set_col_name = "is_privileged";
var set_col_value = true;
using (ae = new AccountEntities())
{
var temp = ae.Accounts.SingleOrDefault(a => a.id == account.id);
temp.Set(set_col_name, set_col_value);
temp.Set("acct_name", "test");
ae.SaveChanges();
}