1

さて、私はサブクラスのすべてのパブリック文字列プロパティを検索するためのtsqlクエリを生成できるデータアクセスオブジェクト用の優れたスーパークラスを作成しようとしています。リフレクションを使用してサブクラスの型を取得し、オブジェクトのすべてのパブリック文字列プロパティを反復処理したいと思います。これらのプロパティ名はデータベースの列名と同じだからです。次に、これらのプロパティ名を使用してtsqlクエリを生成できます。

[警告:ねえ、idはむしろnhibernateを使用しますが、これらの人にそれを使用するように説得する方法はありません]

[ジェネリックでこれを解決することもできますが、ジェネリックはVB.netの人なので怖いと思います(あなたの気持ちを傷つけたら申し訳ありませんが、VB.netが覗き見します;()]

さて、ベースオブジェクトは次のようになります。

public abstract class RepositoryBase
{
   public static IList<RepositoryBase> Search()
   {
        //get all public properties of the inheriting subclass
        // I already have the rest of the search code
   }
}

これも可能ですか、それともお勧めですか?

これを入力している間、私は「それをねじ込み、ジェネリックでそれを行う」のようでした。

読んでくれてありがとう!

4

4 に答える 4

2

派生クラスを「介して」静的メソッドを呼び出すと、コンパイラはメソッドを解決するため、IL には実際に基底クラスが含まれます。例えば:

public class Base
{
    static void Foo() {}
}

public class Derived : Base {}

class Test
{
    static void Main()
    {
        Derived.Foo();
    }
}

Main での呼び出しは、実際には IL で Base.Foo() としてコンパイルされます (少なくとも C# からコンパイルされた場合)。したがって、実行時に元の呼び出しが何であったかを知ることはできません。

ジェネリックが進むべき道のように聞こえます。

于 2009-01-19T17:26:18.510 に答える
1

ええと、あなたがまだ答えを求めていると仮定すると:いいえ。静的メソッドでは、オブジェクトのコンテキストではありません。誰が(を作成せずにStackTrace)あなたに電話をかけたかはわかりません。たとえ電話をかけたとしても、呼び出し元がプロパティを列挙する必要のあるオブジェクトであるかどうかはわかりません。

インスタンスメソッドの場合は、を呼び出すだけGetType()です。

于 2009-01-19T16:52:34.990 に答える
1

ほとんどのリポジトリ パターンは、このような抽象クラスではなくインターフェイスを使用すると思います...

 public class SqlRepository : IRepository {

        DB _db;

        public SqlRepository(DB dataContext) {
            //override the current context
            //with the one passed in
            _db = dataContext;

        } 

        public IQueryable<RepositoryBase> Search() {

           ...

そのように書かれたパターンを見たことがないと思います。可能だと思いますが、あなたが達成しようとしていると思うことを達成できるとは思いません. それをチェックしてください... http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/19a968ce-7d8b-4cf9-b0f0-292464f1e708/

代わりにインターフェイスを使用できない理由はありますか?

于 2009-01-19T16:51:11.917 に答える
0

私はあなたが提案したものに取り組んでいます(VB)。このコードは機能します (スペイン語から翻訳されているため、タイプミスが含まれている可能性があります)。たとえば、次のように使用できます。

Public Sub Main()
   'the SELEC method used below this line is written once and called from every table/class'
   Dim CustList As List(Of CUSTOMER) = CUSTOMER.SELEC("Name = 'Peter'", "Name DESC")
   Dim myOrders As List(Of ORDER) = CustList(0).Orders
   CustList(0).Name = "John"
End Sub


Public Interface ITables 'used solely to unify all the table types'
    '    ReadOnly Property PrimaryKey() As String is better to shadow it from SuperClass TableType'
End Interface

Public Class TableType(Of T As ITables)'this T is what you are looking for'
    Public PrimaryKey As String
    Public Shared Function SELEC(Optional ByVal sWhere As String = "", Optional ByVal sOrderBy As String = "") As List(Of T)
        'shared/static method to fill and return a typed List with the DB rows'
        'can be called using for example Type.SELEC()'
        Dim oConn As New OdbcConnection(My.Settings.ConnectionString)
        Dim oComm As OdbcCommand = oConn.CreateCommand
        oComm.CommandText = "SELECT * FROM " & GetType(T).Name
        If sWhere.Length > 0 Then oComm.CommandText &= " WHERE " & sWhere
        If sOrderBy.Length > 0 Then oComm.CommandText &= " ORDER BY " & sOrderBy
        Dim oListRet As New List(Of T)
        oConn.Open()
        Dim oDR As OdbcDataReader = oComm.ExecuteReader
        Dim oneRow As T
        Do While oDR.Read
            oneRow = Activator.CreateInstance(GetType(T))
            For i = 0 To oDR.FieldCount - 1
                Dim value = oDR.Item(i)
                If TypeOf value Is DBNull Then value = Activator.CreateInstance(oDR.GetFieldType(i)) ' default value'
                oneRow.GetType.GetProperty(oDR.GetName(i)).SetValue(oneRow, value, Nothing)
            Next
            oListRet.Add(oneRow)
        Loop
        oDR.Close()
        oConn.Close()
        oConn.Dispose()
        Return oListRet
    End Function

    Public Function UPDATE(Optional ByVal sWhere As String = "") As Integer
        'not shared but one for all tables'
        'working on this, almost finished'
    End Function
    Shared Function fnPropAttribute(ByVal oProp As PropertyInfo, ByVal sAttrName As String) As String
        'working on this. Returns for example the value of the attribute 'Category' of a field'
        Dim attributes As AttributeCollection = TypeDescriptor.GetProperties(oProp.DeclaringType)(oProp.Name).Attributes
        Dim myAttribute As CategoryAttribute = CType(attributes(GetType(need to know wth to put here)), CategoryAttribute)
        Return myAttribute.Category
    End Function
End Class 'TableType'


Public Class Tables
    Public Class CUSTOMER
        Inherits TableType(Of CUSTOMER)
        Implements ITables
        Public Shadows Const PrimaryKey As String = "idCust"

        'this returns the List(Of Orders) with my idCust'
        Public ReadOnly Property ORDERs() As List(Of ORDER)
            Get
                Return ORDER.SELEC("idCust = " & Me.idCust)
            End Get
        End Property

        Dim _idCust As Integer

        'this Attributes will be used in UPDATE, INSERT, etc'
        'Category 'Columns' is to distingish between DB fields and other possible properties'
        'Description is the ODBCType of the field'
        <Category("Columns"), Description("CHAR")> _
        Public Property idCust() As Integer
            Get
                Return _idCust
            End Get
            Set(ByVal value As Integer)
                _idCust = value
            End Set
        End Property

        Dim _Name As String
        <Category("Columns"), Description("CHAR")> _
        Public Property Name() As String
            Get
                Return _Name
            End Get
            Set(ByVal value As String)
                _Name = value
            End Set
        End Property
        'etc...'
    End Class 'Customer'
    Public Class ORDER
        Inherits TableType(Of ORDER)
        Implements ITables
        Public Shadows Const PrimaryKey As String = "idOrder"

        Dim _idOrder As Integer
        <Category("Columns"), Description("CHAR")> _
        Public Property idOrder() As Integer
            Get
                Return _idOrder
            End Get
            Set(ByVal value As Integer)
                _idOrder = value
            End Set
        End Property

        Dim _idCust As Integer
        <Category("Columns"), Description("CHAR")> _
        Public Property idCust() As Integer
            Get
                Return _idCust
            End Get
            Set(ByVal value As Integer)
                _idCust = value
            End Set
        End Property

        Dim _Artic As String
        <Category("Columns"), Description("CHAR")> _
        Public Property Artic() As String
            Get
                Return _Artic
            End Get
            Set(ByVal value As String)
                _Artic = value
            End Set
        End Property
        'etc...'
    End Class 'Order'
End Class 'Tables'
于 2010-07-03T03:35:03.487 に答える