linq reflection WInForms



我对linq很陌生,正在尝试弄清楚如何完成以下操作:

目前,我有一个Winforms项目,该项目有一个基本窗体,其中DataRow是其成员之一。 我有几个派生的表单根据数据表(SQL查询结果)中的数据填充数据行。 派生窗体上也有控件,这些控件也填充了数据中的值。 单击派生窗体上的"保存"按钮时,将更新基本窗体中的数据行,然后派生窗体通过 DataAdapter 更新数据库。

我想使用 linqs 替换所有 SQL 命令,因此我尝试通过以下方式使用 LINQ 实现此功能:

我在派生窗体中创建了 Linq 查询,并将结果分配给基本窗体中的对象。 我将基窗体中的对象强制转换为 Linq 查询的类类型,并使用反射填充派生窗体上的所有控件。 单击保存按钮时,我更新了对象,但无法更新数据库。

我无法解决的问题是对象更新后如何更新数据库。 此时,我没有用于 linq 查询的数据上下文。

我在 linq 查询中使用 SQL 函数,因此我不得不为这些值创建一个单独的类,因为我收到匿名类型错误。 我可能在这里错过了一些东西。

任何帮助将不胜感激,因为我真的很干净 linq 代码。

编辑

(从布拉德的编辑复制到托马斯的答案):

以下是我的代码的 3 个步骤。

步骤 1 - 从数据库中获取数据的单一记录

private void GetDatabaseDetailData()
{
_db = new PriorityDataContext();
DetailData = (from db in _db.tblDatabases
              where db.DatabaseID == Id
              select db).SingleOrDefault();

DeveloperData = (from db in _db.tblDatabases
                where db.DatabaseID == Id
                select new DeveloperInfo
                {
                    DeveloperName = _db.func_get_employee_name(db.Developer)
                }).SingleOrDefault();
}

步骤 2 - 填充对象中存在名称的所有控件。 对象被强制转换为传递给此方法的特定类型。 为简洁起见,未显示所有代码。

protected virtual void PopulateDetailControlsA(List<Control> controlContainers, string srcDataTableName)
    {
        Object data = null;
        Type type = null;
        switch (srcDataTableName)
        {
            case "tblDatabases" :
                type = typeof(tblDatabase);
                data = (tblDatabase)DetailData;
                break;
        }
        if (type != null)
        {
            var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (var controlContainer in controlContainers)
            {
                foreach (var propertyInfo in properties)
                {
                    if (!ControlExists(controlContainer, propertyInfo.Name)) continue;
                    var txtControl = controlContainer.Controls[propertyInfo.Name] as ExtendedTextBox;
                    if (txtControl != null)
                    {
                        try
                        {
                            var value = propertyInfo.GetValue(data, null).ToString();
                            if (propertyInfo.Name == "row_oper_name" || propertyInfo.Name == "row_last_chng_oper_name")
                            {
                                txtControl.Text = RowOperatorData.RowOperatorName;
                                txtControl.ValueMember = propertyInfo.GetValue(data, null).ToString();
                            }
                            else
                                txtControl.Text = value;
                        }
                        catch (NullReferenceException)
                        {
                        }
                        continue;...........

步骤3 - 尝试将更改保存回派生发件人中的数据库。

private void SaveData()
{
           try
        {
            _db.SubmitChanges();
        }
        catch (Exception sqlException)
        {
        }
}

我真正不清楚的是如何将结果集存储在基本窗体中,以便我可以对许多不同的查询使用相同的代码。 DataRow 运行良好,因为我将一些代码用于超过 25 个派生表单。

如果我理解正确,您可以在派生形式中创建DataContext,然后使用它编写一些查询(以派生形式)。为了能够更新数据库,查询必须返回从表中获取的实体(即 select 子句应该只返回实体)。例如:

DataContext db = // ...
var q = from p in db.Things
        where p.Some > 10 select p;

如果随后修改实体,则可以使用 db.SubmitChanges() 将更改(对实体对象所做的)存储到数据库。为此,您需要原始db值。

在你的方案中,需要将DataContext(作为字段)存储在派生窗体中。如果您需要从基本窗体执行更新,那么我建议您定义一个虚拟方法:

// Base form
protected abstract void UpdateDatabase();
// Derived from with field 'db' storing 'DataContext'
protected override void UpdateDatabase() {
    db.SumbitChanges();
}

相关内容

  • 没有找到相关文章

最新更新