これは、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();
}
}