【问题标题】:C# Reflection. Set TableAdapter ConnectionStringC# 反射。设置 TableAdapter 连接字符串
【发布时间】:2015-06-25 20:36:28
【问题描述】:

我希望有人可以帮助解决这个问题。我一直在尝试为 WinForm 创建一个新的基类。我想做的是让这个基类遍历它上面的所有表格适配器并更新它们的连接字符串,而无需任何人向表单添加任何代码。他们只是将表格适配器放在表单上,​​不用担心连接字符串设置,因为它们都在基类中处理。

我遇到的问题是我的反射代码可以找到该属性但无法设置它。有人可以帮忙吗?

以下是代码(更新)

public class cFormWS : Form
{
    public string ConnectionStringToUse { get; set; }

    public cFormWS()
    {
        Load += cFormWS_Load;
    }

    void cFormWS_Load(object sender, EventArgs e)
    {
        InitiliseTableAdapters();
    }

    private void InitiliseTableAdapters()
    {          
        var ListOfComponents = EnumerateComponents();

        foreach (var ItemComp in ListOfComponents)
        {
            if (ItemComp.ToString().ToLower().EndsWith("tableadapter"))
            {
                var ItemCompProps = ItemComp.GetType().GetRuntimeProperties();

                var TASQLConnection = ItemCompProps.FirstOrDefault(w => w.PropertyType == typeof(System.Data.SqlClient.SqlConnection));

                if (TASQLConnection != null)
                {
                    var property = typeof(System.Data.SqlClient.SqlConnection).GetProperty("ConnectionString");

                    // How do I set the value ?

                    string value = "some new connection string";

                    var ConvertedProperty = Convert.ChangeType(value, property.PropertyType);

                    // tried seting value.  not working "object does not match target type"
                    property.SetValue(TASQLConnection, ConvertedProperty, null);


                    //// tried using a method.  not working "object does not match target type"
                    //var m = property.SetMethod;
                    //ParameterInfo[] parameters = m.GetParameters();
                    //m.Invoke(m, parameters); // m.Invoke(this, parameters); // m.Invoke(ItemComp, parameters);
                }                      
            }                
        }
    }

    private IEnumerable<Component> EnumerateComponents()
    {
        return from field in GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
               where typeof(Component).IsAssignableFrom(field.FieldType)
               let component = (Component)field.GetValue(this)
               where component != null
               select component;
    }  

【问题讨论】:

  • 你不需要在这里反射(或者你的代码对它的预期用途没有任何意义)。
  • 据我所知,没有其他方法可以自动完成我想做的事情。
  • 只有在 TableAdapter 不共享公共基类时才会这样。可以? MSDN 在这方面比较模糊。
  • 即使在这种情况下,您仍然可以通过将已知接口应用于生成的类并将ItemComp 转换为该类来避免反射。
  • TableAdapter 继承自 Component。将接口应用于生成的类将意味着当它重新生成时它会丢失接口吗?

标签: c# winforms reflection tableadapter


【解决方案1】:

编辑:

当您执行SetValue 时,您需要传入您希望设置属性的对象。

  • 在您的第一个示例代码中,您传入了ItemComp:这是不正确的,因为ConnectionStringSqlConnection 的一个属性ItemComp 的一个属性
  • 在您编辑的问题(以及我的原始答案)中,您传递了TASqlConnection。但是,这不是对象,而是对象的PropertyInfobased
  • 正确的方法是从ItemComp对象中获取值并传入:

property.SetValue(TASQLConnection.GetValue(ItemComp), ConvertedProperty, null);

原始(错误)答案:

您正在尝试设置ItemCompConnectionString 属性。 ConnectionString 不是TableAdapter 的属性,而是SqlConnection 的属性(这是TableAdapter 的属性)。

设置属性的正确方法是这样的:

property.SetValue(TASQLConnection, ConvertedProperty, null);

【讨论】:

  • 不。相同的错误信息。我已经尝试了很多不同的组合。
  • 是的,问题在于您传递的是PropertyInfo-object,而不是实际的对象。请参阅我编辑的答案以获取解释和修复
  • 感谢您的回答。它仍然无法正常工作。我现在有一个不同的错误。调用的目标已抛出异常。
  • 看看内部异常。如果您使用的是示例代码,则连接字符串的格式不正确,实际分配将失败
  • 是的,你是对的。我不认为它需要是一个有效的连接字符串,因为它当时没有连接,但它看起来像集合检查它。
猜你喜欢
  • 1970-01-01
  • 2017-02-27
  • 1970-01-01
  • 2011-05-22
  • 1970-01-01
  • 2011-06-05
  • 2020-04-14
  • 2016-06-22
  • 1970-01-01
相关资源
最近更新 更多