4

式を受け取り、Linq-To-Sqlを使用して必要なSQLステートメントを生成できるリポジトリモデルを作成したいと思います。

たとえば、次のような関数があります。

// Possible criteria
Expression<Func<Purchase,bool>> criteria1 = p => p.Price > 1000;

// Function that should take that criteria and convert to SQL statement
static IEnumerable<Customer> GetCustomers (Expression<Func<Purchase,bool>> criteria)
{
   // ...
}

関数内で、Linq-To-Sqlを使用して条件をSQLステートメントに変換したいと思います。

DataContext.Log実行されたクエリを表示し、実行される前に完全なクエリを表示するために使用できることを認識していますDataContext.GetCommand(query).CommandText。ただし、表現全体の一部を生成したいのですが。

私が達成したいと思っているのは、リポジトリに基盤となるテクノロジ(Linq-to-Sql、Dapperなど)を抽象化することです。そうすれば、式をリポジトリに渡し、適切なステートメントを生成し、適切なテクノロジを使用して実行することができます。

4

2 に答える 2

2

あなたはこのようなことをすることができます:

string sql = DataContext.GetTable<Customer>().Where(criteria).ToString();

ToString()はSQL式を提供します。次に、正規表現を使用してWHERE句を引き出すことができます。

于 2011-11-23T12:09:35.950 に答える
1

これは、Where関数で使用する独自の述語を作成するために使用するコードの抜粋です。コンパイラは無数の複雑なオブジェクトに対応できないため、自分で処理する必要があります。

基本的に、コードには無数の(文字列コード、文字列交換)タプルが渡され、式を作成して、Security.Code == tuple.Code AND(Security.MasterExchangeForStocksId == tuple.exchange OR SecurityExchangeId)を持つすべてのセキュリティオブジェクトを取得します。 == tuple.exchange)。

CreateTrEntitiesAsync()は、DbSetSecurityプロパティを持つEntityFrameworkコンテキストを返すだけです。

public async Task<Security[]> GetSecurities(IEnumerable<(string code, string exchange)> tickers)
{
    using (var ctx = await CreateTrEntitiesAsync())
    {
        var securityExpr = Expression.Parameter(typeof(Security), "security");
        Expression expr = null;
        Expression exprToadd;

        foreach (var item in tickers)
        {
            exprToadd = Expression.And(
                Expression.Equal(Expression.Property(securityExpr, nameof(Security.Code)), Expression.Constant(item.code)),
                Expression.Or(
                    Expression.Equal(Expression.Property(Expression.Property(securityExpr, nameof(Security.Exchange)), nameof(Exchange.MasterExchangeForStocksId)), Expression.Constant(item.exchange)),
                    Expression.Equal(Expression.Property(securityExpr, nameof(Security.ExchangeId)), Expression.Constant(item.exchange))
                )
            );

            if (expr == null)
                expr = exprToadd;
            else
                expr = Expression.Or(expr, exprToadd);
        }

        var criteria = Expression.Lambda<Func<Security, bool>>(expr, new ParameterExpression[] { securityExpr });
        var items = ctx.Securities.Where(criteria);
        return await items.ToArrayAsync();
    }
}
于 2019-07-16T09:30:02.707 に答える