Vb.net 创建自定义linq方法以创建sql表达式

Vb.net 创建自定义linq方法以创建sql表达式,vb.net,linq,fluent-migrator,Vb.net,Linq,Fluent Migrator,我正在尝试创建与FluentMigrator中类似的自定义linq方法(和类)。我想执行这样的调用: Create.Table("Users") .WithColumn("UserId").AsInt32().Identity().PrimaryKey() .WithColumn("GroupId").AsInt32().NotNullable() .WithColumn("UserName").AsString(32).NotNullable() .WithCo

我正在尝试创建与FluentMigrator中类似的自定义linq方法(和类)。我想执行这样的调用:

Create.Table("Users")
    .WithColumn("UserId").AsInt32().Identity().PrimaryKey()
    .WithColumn("GroupId").AsInt32().NotNullable()
    .WithColumn("UserName").AsString(32).NotNullable()
    .WithColumn("Password").AsString(32).NotNullable();
我已经实现了一个类来处理
Create.Table
WithColumn
。这两个方法都返回表示要创建的表的相同类类型

我不明白的是如何创建其他方法(AsInt32,Identity,…)。这些方法不在我的表类上操作,而是在由
WithColumn
方法创建的列类上操作

我必须如何定义我的类,以便将表类链接到列类,反之亦然

以下是我到目前为止提出的代码:

Friend Class PdmCreateExpression
    Public Property Schema As String
    Public Property TableName As String
    Public Property Columns As List(Of PdmColumn)

    Public Sub New()
        Columns = New List(Of PdmColumn)
    End Sub

    Public Function Table(tableName As String) As PdmCreateExpression
        Me.TableName = tableName
        Return Me
    End Function

    Public Function WithColumn(columnName As String) As PdmCreateExpression
        Dim newColumn = New PdmColumn(columnName)
        Columns.Add(newColumn)
        Return Me
    End Function

    Public Overrides Function ToString() As String
        Dim sqlString = "CREATE TABLE "

        If Not String.IsNullOrEmpty(Schema) Then sqlString += "[" + Schema + "]."
        sqlString += "[" + TableName + "] ("
        sqlString += String.Join(",", Columns.Select(Function(c) "[" + c.Name + "]"))
        sqlString += ")"

        Return sqlString
    End Function

End Class

Friend Class PdmColumn
    Public Property Name As String
    Public Property SqlType As String

    Public Sub New(name As String)
        Me.Name = name
    End Sub

    Public Function AsSqlType(sqlType As String)
        Me.SqlType = sqlType
        Return Me
    End Function
End Class

Friend MustInherit Class MigratorBase
    Protected Property _DbConnection As SqlConnection
    Protected Property Expressions As List(Of PdmCreateExpression)

    Sub New(dbConnection As SqlConnection)
        _DbConnection = dbConnection
        Expressions = New List(Of PdmCreateExpression)()
    End Sub

    Public MustOverride Sub Install()

    Public Function Create() As PdmCreateExpression
        Dim newExpression = New PdmCreateExpression()
        Expressions.Add(newExpression)
        Return newExpression
    End Function
End Class
使用上述代码,我可以创建如下查询:

Dim migrator = New MigratorBase(_DbConnection)
Dim sql = migrator.Create.Table("VersionInfo") _
                .WithColumn("Version") _
                .WithColumn("TimestampCreated") _
                .ToString()

这些不是LINQ方法;他们被称为

您所追求的可以通过所谓的“标记接口”实现:


你能展示一下你当前的一些代码吗?我添加了目前为止的实现。谢谢@Anton Gogolev。我把你的代码复制到clean C#项目中,并让它进行编译。我可能错过了什么,因为它不起作用:我可以像(new TableMap()).WithColumn().WithColumn()这样调用,但我不能在WithColumn调用后插入例如.AsInt32()。它既不编译也不识别AsInt32。你能告诉我我做错了什么吗?我尽了最大努力让上面的代码工作,但我失败了。有人能证明我没有破译密码吗?上面的代码没有编译。我必须在AsIn32中应用强制类型转换,并且不能像下面这样为空:“return(ColumnMap)colmn”。此外,我还必须将“公共静态TableConvertibleExtensionTargetExtensions”更改为“静态类TableConvertibleExtensionTargetExtensions”。但这不可能是它不起作用的原因。任何帮助都将不胜感激。
interface ITableConvertibleExtensionTarget
{    
}

interface ITableExtensionTarget : ITableConvertibleExtensionTarget
{
}

interface IColumnExtensionTarget
{
}

class TableMap : ITableExtensionTarget
{    
}

class ColumnMap : IColumnExtensionTarget, ITableConvertibleExtensionTarget
{    
}

static class ColumnMapExtensions
{
    public static ColumnMap AsInt32(this IColumnExtensionTarget column)
    {
        // Mapping voodoo
        return column;
    }

    public static ColumnMap NotNullable(this IColumnExtensionTarget column)
    {
        // More voodoo
        return column;
    }
}

public static TableConvertibleExtensionTargetExtensions
{
    public static TableMap WithColumn(this ITableConvertibleExtensionTarget table)
    {
        return new TableMap(...);
    }
}