2015-12-14 5 views
0

Я пытаюсь создать собственные методы (и классы) linq, похожие на те, которые могут быть найдены в FluentMigrator. Я хочу, чтобы выполнить вызовы как этот:Создайте собственные методы linq для создания выражений sql

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. Оба метода возвращают тот же тип класса, который представляет создаваемую таблицу.

Я не понимаю, как создать другие mehtods (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() 
+0

Можете ли вы показать некоторые из текущего кода? –

+0

Я добавил реализацию, которую я имею до сих пор. – Sascha

ответ

0

Это не методы LINQ; они называются extension methods.

То, что вы после того, как можно сделать с помощью так называемых «маркерных интерфейсов»:

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(...); 
    } 
} 
+0

Спасибо @ Антон Гоголев. Я скопировал ваш код для очистки проекта C# и получил его для компиляции. Я, вероятно, что-то пропустил, потому что он не работает: я могу сделать вызов (new TableMap()). WithColumn(). WithColumn(), но я не могу вставить, например. .AsInt32() после вызова WithColumn. Он также не компилирует и не распознает IntelliSense AsInt32. Можете ли вы сказать мне, что я делаю неправильно? – Sascha

+0

Я сделал все возможное, чтобы этот код работал, но мне не удалось. Может ли кто-нибудь проверить, что я не нарушил код? Вышеприведенное не компилировалось. Мне пришлось применять броски в AsIn32 и NotNullable следующим образом: «return (ColumnMap) colmn». Также мне пришлось изменить «public static TableConvertibleExtensionTargetExtensions» на «static class TableConvertibleExtensionTargetExtensions». Но это не может быть причиной того, что это не сработает. Любая помощь приветствуется. – Sascha