我目前正在开发一个允许连接到多个提供者特定数据库的程序,所以显然我使用非提供者特定的类(在System.Data.Common中)来处理这些不同的连接一旦已经通过使用提供程序的实现来实例化连接或数据适配器。
但是,我想根据MSDN(http://msdn.microsoft.com/en-us/library/6d1wk41s.aspx)使用RowUpdated和RowUpdating事件,这些事件应该是DataAdapter基类的一部分。但显然事实并非如此,因为这些事件只是通过DbDataAdapter的特定于提供者的实现(如SqlDataAdapter,OleDbDataAdapter等)实现的。
我的主要目标是能够通过使用通用DbDataAdapter类来处理这些事件,并且必须将事物转换回数据适配器的特定于提供程序的实现的派生类将是一件非常大的痛苦。
这样做的任何光鲜的想法?
答案 0 :(得分:3)
我做了很多在线搜索,除了只是将实例重新转换回派生类以访问这些事件之外,我没有找到任何具体内容。
因此,通过使用扩展方法,我向DbDataAdapter抽象类添加了两个新方法,允许为这两个特定事件添加事件处理程序,这是我的实现(编辑于2013年4月23日处理)实例或静态处理程序方法):
using System;
using System.Data.Common;
using System.Reflection;
namespace Extensions
{
/// <summary>
/// Delegate event handler used with the <c>DbDataAdapter.RowUpdated</c> event.
/// </summary>
public delegate void RowUpdatedEventHandler(object sender, RowUpdatedEventArgs e);
/// <summary>
/// Delegate event handler used with the <c>DbDataAdapter.RowUpdating</c> event.
/// </summary>
public delegate void RowUpdatingEventHandler(object sender, RowUpdatingEventArgs e);
public static class DbDataAdapterExtension
{
private static EventInfo GetEvent(string eventName, Type type)
{
return type.GetEvent(eventName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
}
/// <summary>
/// Registers a <c>RowUpdatedEventHandler</c> with this instance's <c>RowUpdated</c> event.
/// </summary>
/// <param name="handler">The event handler to register for the event.</param>
/// <returns><c>true</c> if the event handler was successfully registered, otherwise <c>false</c>.</returns>
public static bool AddRowUpdatedHandler(this DbDataAdapter adapter, RowUpdatedEventHandler handler)
{
EventInfo updEvent = GetEvent("RowUpdated", adapter.GetType());
if (updEvent != null)
{
try
{
if (handler.Method.IsStatic)
{
updEvent.AddEventHandler(adapter, Delegate.CreateDelegate(updEvent.EventHandlerType, handler.Method));
}
else
{
updEvent.AddEventHandler(adapter, Delegate.CreateDelegate(updEvent.EventHandlerType, handler.Target, handler.Method));
}
return true;
}
catch { }
}
return false;
}
/// <summary>
/// Registers a <c>RowUpdatingEventHandler</c> with this instance's <c>RowUpdating</c> event.
/// </summary>
/// <param name="handler">The event handler to register for the event.</param>
/// <returns><c>true</c> if the event handler was successfully registered, otherwise <c>false</c>.</returns>
public static bool AddRowUpdatingHandler(this DbDataAdapter adapter, RowUpdatingEventHandler handler)
{
EventInfo updEvent = GetEvent("RowUpdating", adapter.GetType());
if (updEvent != null)
{
try
{
if (handler.Method.IsStatic)
{
updEvent.AddEventHandler(adapter, Delegate.CreateDelegate(updEvent.EventHandlerType, handler.Method));
}
else
{
updEvent.AddEventHandler(adapter, Delegate.CreateDelegate(updEvent.EventHandlerType, handler.Target, handler.Method));
}
return true;
}
catch { }
}
return false;
}
}
}
我正在使用基础RowUpdatedEventArgs&amp; RowUpdatingEventArgs用于返回给委托的事件参数,因此如果您需要特定于提供者的成员,这些成员只能通过从上述两个基本事件args类派生的提供者定义的类来获得,那么它们将需要转换为那些类。否则,它工作正常,现在我可以从DbDataAdapter类中获得与提供程序无关的事件处理程序(这是Microsoft应该如何实现它们的开始)。
干杯!
答案 1 :(得分:0)
谢谢 - 非常有用!
也许有人在Visual Basic中需要这个
这样称呼它为例:
Imports YourProject.DbDataAdapterExtension
。 。
Dim HandleOnRowUpd As RowUpdatedEventHandler = AddressOf OnRowUpdated
Dim TrueFalse As Boolean = YourDataAdapter.AddRowUpdatedHandler(HandleOnRowUpd)
Imports System.Data.Common
Imports System.Reflection
Imports System.Runtime.CompilerServices
' Namespace Extensions
''' <summary>
''' Delegate event handler used with the <c>DbDataAdapter.RowUpdated</c> event.
''' </summary>
'''
Public Delegate Sub RowUpdatedEventHandler(sender As Object, e As RowUpdatedEventArgs)
''' <summary>
''' Delegate event handler used with the <c>DbDataAdapter.RowUpdating</c> event.
''' </summary>
'''
Public Delegate Sub RowUpdatingEventHandler(sender As Object, e As RowUpdatingEventArgs)
Public Module DbDataAdapterExtension
Sub New()
End Sub
Private Function GetEvent(eventName As String, type As Type) As EventInfo
Return type.GetEvent(eventName, BindingFlags.[Public] Or BindingFlags.Instance Or BindingFlags.DeclaredOnly)
End Function
''' <summary>
''' Registers a <c>RowUpdatedEventHandler</c> with this instance's <c>RowUpdated</c> event.
''' </summary>
''' <param name="handler">The event handler to register for the event.</param>
''' <returns><c>true</c> if the event handler was successfully registered, otherwise <c>false</c>.</returns>
'''
<Extension> Public Function AddRowUpdatedHandler(adapter As DbDataAdapter, handler As RowUpdatedEventHandler) As Boolean
Dim updEvent As EventInfo = GetEvent("RowUpdated", adapter.[GetType]())
If updEvent IsNot Nothing Then
Try
If handler.Method.IsStatic Then
updEvent.AddEventHandler(adapter, [Delegate].CreateDelegate(updEvent.EventHandlerType, handler.Method))
Else
updEvent.AddEventHandler(adapter, [Delegate].CreateDelegate(updEvent.EventHandlerType, handler.Target, handler.Method))
End If
Return True
Catch
End Try
End If
Return False
End Function
''' <summary>
''' Registers a <c>RowUpdatingEventHandler</c> with this instance's <c>RowUpdating</c> event.
''' </summary>
''' <param name="handler">The event handler to register for the event.</param>
''' <returns><c>true</c> if the event handler was successfully registered, otherwise <c>false</c>.</returns>
'''
<Extension> Public Function AddRowUpdatingHandler(adapter As DbDataAdapter, handler As RowUpdatingEventHandler) As Boolean
Dim updEvent As EventInfo = GetEvent("RowUpdating", adapter.[GetType]())
If updEvent IsNot Nothing Then
Try
If handler.Method.IsStatic Then
updEvent.AddEventHandler(adapter, [Delegate].CreateDelegate(updEvent.EventHandlerType, handler.Method))
Else
updEvent.AddEventHandler(adapter, [Delegate].CreateDelegate(updEvent.EventHandlerType, handler.Target, handler.Method))
End If
Return True
Catch
End Try
End If
Return False
End Function
End Module
' End Namespace