Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net .NET-有没有一种方法可以通过编程方式填充强类型数据集中的所有表?_Vb.net_Visual Studio 2008_Reflection_Ado.net_Strongly Typed Dataset - Fatal编程技术网

Vb.net .NET-有没有一种方法可以通过编程方式填充强类型数据集中的所有表?

Vb.net .NET-有没有一种方法可以通过编程方式填充强类型数据集中的所有表?,vb.net,visual-studio-2008,reflection,ado.net,strongly-typed-dataset,Vb.net,Visual Studio 2008,Reflection,Ado.net,Strongly Typed Dataset,我有一个SQL Server数据库,我已经为它创建了一个强类型数据集(使用Visual Studio 2008中的数据集设计器),因此向导为我创建了所有适配器和select命令等 这是一个很大程度上是静态数据的小型数据库,因此我希望在启动时将此数据库的全部内容拉入我的应用程序中,然后使用LINQ根据需要获取单独的数据片段。我不想对每个适配器填充调用进行硬编码,而是想看看是否有办法实现自动化(可能是通过反射) 因此,不是: Dim _ds As New dsTest dsTestTableAdap

我有一个SQL Server数据库,我已经为它创建了一个强类型数据集(使用Visual Studio 2008中的数据集设计器),因此向导为我创建了所有适配器和select命令等

这是一个很大程度上是静态数据的小型数据库,因此我希望在启动时将此数据库的全部内容拉入我的应用程序中,然后使用LINQ根据需要获取单独的数据片段。我不想对每个适配器填充调用进行硬编码,而是想看看是否有办法实现自动化(可能是通过反射)

因此,不是:

Dim _ds As New dsTest
dsTestTableAdapters.Table1TableAdapter.Fill(_ds.Table1)
dsTestTableAdapters.Table2TableAdapter.Fill(_ds.Table2)
<etc etc etc>
Dim\u ds作为新的数据测试
dsTestTableAdapters.Table1TableAdapter.Fill(_ds.Table1)
dsTestTableAdapters.Table2TableAdapter.Fill(_ds.Table2)
我更喜欢这样做:

Dim _ds As New dsTest
For Each tableName As String In _ds.Tables
    Dim adapter as Object = <routine to grab adapter associated with the table>
    adapter.Fill(tableName)
Next
Dim\u ds作为新的数据测试
在_ds.Tables中将每个表名作为字符串
作为对象的Dim适配器=
adapter.Fill(表名)
下一个
这甚至是远程的可行吗?我已经做了大量的搜索,我不认为这是一个不寻常的请求,但我一定是问错了问题,或者我只是奇怪地想这样做

我承认,我通常更喜欢使用未绑定控件,而不是使用强类型数据集(我更喜欢直接编写SQL),但我的公司希望走这条路,所以我正在研究它。我认为,随着表的添加,我们可以使用VisualStudio中的设计器刷新数据集,而不必对底层DB代码进行太多更改


任何帮助都将不胜感激。提前谢谢

不存在任何允许您自动填充整个类型化数据集的api,或者在支持此功能的类型化数据集中不生成此类代码。这也很难做到,因为TableAdapters没有一个公共基类可以让您做到这一点

如果确实需要这样做,则必须维护DataTable类型名称和TableAdapter类型名称的集合,并迭代该集合以执行数据集填充

所以我建议按照您的第一个代码示例所述,以“硬代码”的方式填充每个表的数据集

编辑 这里有一个可能的解决方案

定义接口ITableAdapter,如下所示

public interface ITableAdapter<TDataTable> : where TDataTable : DataTable
{
    TDataTable SelectAll();
}
公共接口ITableAdapter:其中TDataTable:DataTable
{
t数据表SelectAll();
}
所有TableAdapter都是分部类,所以您可以扩展它们并在TableAdapter的分部自定义类中添加自定义代码。在类型化数据集中的每个TableAdapter上实现ITableAdapter。所以它可能看起来像这样

public partial class YourTableAdapter : ITableAdapter<YourDataSet.YourDataTableDataTable>
{
    public YourDataSet.YourDataTableDataTable SelectAll()
    {
         return this.GetData();
    }
}
public partial class YourTableAdapter : ITableAdapter<YourDataSet.YourDataTableDataTable>
{
    //No code required here, since Fill method is already defined in TableAdapter :)
}
public分部类YourTableAdapter:ITableAdapter
{
public YourDataSet.YourDataTableDataTable SelectAll()
{
返回这个.GetData();
}
}
现在,您可以迭代程序集中的每种类型,过滤ITableAdapter类型的类型,并对每种类型调用SelectAll()方法将其填充到数据集中。:)

编辑2 我刚刚为这个问题想出了另一个优雅的解决方案。您只需定义接口ITableAdapter,以映射数据集设计器生成的TableAdapter中已经实现的方法

public interface ITableAdapter<TDataTable> : where TDataTable : DataTable
{
    void Fill(TDataTable);
}
公共接口ITableAdapter:其中TDataTable:DataTable
{
空隙填充(TDataTable);
}
并像这样扩展TableAdapter部分类

public partial class YourTableAdapter : ITableAdapter<YourDataSet.YourDataTableDataTable>
{
    public YourDataSet.YourDataTableDataTable SelectAll()
    {
         return this.GetData();
    }
}
public partial class YourTableAdapter : ITableAdapter<YourDataSet.YourDataTableDataTable>
{
    //No code required here, since Fill method is already defined in TableAdapter :)
}
public分部类YourTableAdapter:ITableAdapter
{
//此处不需要代码,因为已在TableAdapter中定义了填充方法:)
}

好的,我想我已经解决了这个问题,我只想分享一下结果,因为很可能有人和我一样疯狂

基本上,所有的神奇都是通过几个LINQ查询和反射实现的。在本例中,我们将假设:

  • 在Visual Studio 2008中,有一个使用数据集设计器创建的强类型数据集,名为dsTest。模块级变量保存此数据集的一个实例,并被称为(足够合适),m_数据集
  • 这些表本身都遵循标准的SQL Server命名约定,以“tbl”开头
  • 作为此向导的一部分,为名为dsTestTableAdapters的命名空间内的每个表创建了一系列表适配器
  • 每个适配器都是根据表命名的(因此,如果我们有“tblThingy”,那么将创建一个名为“tblThingyTableAdapter”的适配器)
  • 由于缺少更好的名称空间,应用程序位于名为MyNamespace的名称空间中
  • 下面是在表单加载时调用的例程:

    Private Sub PopulateDataSet()
        ' Get our table adapters
        Dim adapters As List(Of Type) = (From t As Type In System.Reflection.Assembly.GetExecutingAssembly.GetTypes Where t.Namespace = "MyNameSpace.dsTestTableAdapters" And t.Name.StartsWith("tbl") Select t).ToList
    
        ' Initialize our dataset
        m_DataSet = New dsUtility
    
        ' Get our table names
        Dim tableNames as List(Of String) = (From dtbl As DataTable In m_DataSet.Tables Select dtbl.TableName).ToList
    
        ' Loop through each table name and fill the table with the corresponding adapter
        For Each iter As String In tableNames
            ' Grab the corresponding adapter name 
            Dim tableName As String = iter ' Grab a copy of the table name to avoid LINQ issues with iteration variables
            Dim adapterType As Type = (From t As Type In adapters Where t.Name.StartsWith(tableName) Select t).First
    
            ' Given the adapter type name, use Reflection to create an instance
            Dim adapter As Object = Activator.CreateInstance(adapterType)
    
            ' Use the instance to fill the appropriate table
            adapter.Fill(m_DataSet.Tables(tableName))
        Next
    End Sub
    

    我试过了,效果很好。谢谢大家,谢谢你们的帮助,我希望你们觉得这很有用

    我想你只有一个问题!
    如果此类型化数据集在表之间具有关系,则此代码将不会以正确的顺序加载数据表

    迈克,谢谢你周到的解决方案。和您一样,我一直在寻找一种方法来完成您所做的工作,并使用相同的机制来避免出现丑陋的switch语句(在C#中),该语句必须对生成的TableAdapter进行装箱以执行数据绑定更新

    我将您的VB代码转换为C#,如下所述。我做了两个更改(我正在使用VS Express 2010和.NET 4.0):

  • 我将StartWith(“tbl”)方法更改为EndsWith(“TableAdapter”),因为TableAdapters命名空间中的许多生成成员(不仅仅是TableAdapter)以“tbl”开头(假设您希望或需要遵循该约定),但只有TableAdapter以“TableAdapter”结尾

  • 我更改了对Fill方法的调用,因为VS在生成时告诉我“adapter”(在调试器中看起来确实像TableAdapter)引用的对象没有Fill方法,也没有Fill扩展方法。因此,我无法执行填充。我一点也不害怕