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.idaccount.acct_nameaccount.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();
    }