动态LINQ -实体框架6 -更新记录的动态选择

本文关键字:动态 新记录 选择 更新 框架 LINQ 实体 | 更新日期: 2023-09-27 18:15:55

c#菜鸟。下面是我的代码,已经尝试了几个小时,现在得到这个更新我的数据库中的一些字段,并尝试了许多不同的实现没有运气。

        // Select all fields to update
        using (var db = new Entities())
        {
            // dbFields are trusted values
            var query = db.tblRecords
                         .Where("id == " + f.id)
                         .Select("new(" + string.Join(",", dbFields.Keys) + ")");
            foreach (var item in query)
            {
                foreach (PropertyInfo property in query.ElementType.GetProperties())
                {
                    if (dbFields.ContainsKey(property.Name))
                    {
                        // Set the value to view in debugger - should be dynamic cast eventually
                        var value = Convert.ToInt16(dbFields[property.Name]);
                        property.SetValue(item, value);
                        // Something like this throws error 'Object does not match target type'
                        // property.SetValue(query, item);
                    }
                }
            }
            db.SaveChanges();
        }

上面的代码在运行时不会导致对DB的任何更改。显然,这段代码需要一点清理,但我试图得到的基本功能的工作。我相信我可能需要做的是以某种方式重新应用'项目'回到'查询',但我没有运气得到的工作,无论我尝试什么实现,我总是收到'对象不匹配的目标类型'。

这个半类似的问题重申,但不是很清楚,因为我使用的是动态LINQ查询,不能直接引用属性名。https://stackoverflow.com/a/25898203/3333134

动态LINQ -实体框架6 -更新记录的动态选择

实体框架将为您执行实体更新,而不是自定义结果。您的tblRecords包含许多实体,如果您希望实体框架提供帮助,这就是您想要操作的实体。删除您的投影(对Select的调用),查询将直接返回对象(有太多的列,是的,但我们将在后面讨论)。

动态更新的执行方式与c#中任何其他动态赋值的执行方式相同,因为您有一个正常的对象来处理。实体框架将跟踪您所做的更改,并在调用SaveChanges时,将生成并执行相应的SQL查询。

然而,如果您想首先优化并停止在内存中选择和创建所有值,即使是那些不需要的值,您也可以从内存中执行更新。如果您自己创建了正确类型的对象并分配了正确的ID,那么您可以使用Attach()方法将其添加到当前上下文中。从那时起,任何更改都将由实体框架记录,当您调用SaveChanges时,所有内容都应发送到数据库:

// Select all fields to update
using (var db = new Entities())
{
    // Assuming the entity contained in tblRecords is named "ObjRecord"
    // Also assuming that the entity has a key named "id"
    var objToUpdate = new ObjRecord { id = f.id };
    // Any changes made to the object so far won't be considered by EF
    // Attach the object to the context
    db.tblRecords.Attach(objToUpdate);
    // EF now tracks the object, any new changes will be applied
    foreach (PropertyInfo property in typeof(ObjRecord).GetProperties())
    {
        if (dbFields.ContainsKey(property.Name))
        {
             // Set the value to view in debugger - should be dynamic cast eventually
             var value = Convert.ToInt16(dbFields[property.Name]);
             property.SetValue(objToUpdate, value);
        }
    }
    // Will only perform an UPDATE query, no SELECT at all
    db.SaveChanges();
}

当你做SELECT NEW ...时,它只选择特定的字段,不会为你跟踪更新。我认为如果你改变你的查询是这样的,它将工作:

var query = db.tblRecords.Where(x=>x.id == id);