1

私は、2 つの異なる DB で 2 つのモデルの奇妙な結合方法のように見えるものを構築しようとしています。最初にクエリを実行してから、ID の小さなリストを返して別のデータベースで検索できます。ラムダ関数を使用して Id リストのサブクエリを実行できません。ジェネリックをリンクする Id セレクター関数がありますが、where 句では、誰がソース タイプをリンクするかわからないため、動作します。オブジェクトを Id の渡された関数に渡すため.Where(TSource => idlist.Contains(Idselector)、サンプル コードは、コードが原因で中断するところまで以下に示しList.Conatinsます。私が動揺しているので、誰かが助けることができれば大歓迎です

public static Foo JoinTwoModels<T1,T2>(
           DbSet Dbs1,
           DbSet Dbs2,
           Expression<Func<T1, object>> Id1,
           Expression<Func<T1, dynamic>> Selector1,
           Expression<Func<T1, bool>> Search1,
           Expression<Func<T2, object>> Id2,
           Expression<Func<T2, dynamic>> Selector2)
        {
            var Output1 = Queryable.OfType<T1>(Dbs1);

            var Output2 = Queryable.OfType<T2>(Dbs2);

            List<dynamic> Result1 = Output1.Where(Search1).Select(Selector1).ToList();

            List<object> idList = new List<object>();

            PropertyInfo p1 = Result1[0].GetType().GetProperty("Id");

            foreach (var o1 in Result1)
            {
                idList.Add(p1.GetValue(o1));
            }

            //Query result entries into db
            List<T2> Result2 = Output2.Where(idlist.contains(Id2)).ToList();
4

1 に答える 1

0

このようなものはどうですか:

public class Foo
{
    public int Context;
    public string Data;
}

public class Bar
{
    public int Context;
    public string Data;
}

public static IEnumerable<TOutput> JoinTwoModels<T1, T2, TIdent, TOutput>(
    IEnumerable<T1> sourceA,
    IEnumerable<T2> sourceB,
    Func<T1, TIdent> idSelectorA,
    Func<T2, TIdent> idSelectorB,
    Func<T1, TOutput> selectorA,
    Func<T2, TOutput> selectorB)
{

    var queryA = sourceA
            .Select(x => new {Value = selectorA(x),Id = idSelectorA(x)});

    var queryB = sourceB
            .Select(y => new {Value = selectorB(y),Id = idSelectorB(y)})
            .Where(y => queryA.Select(x => x.Id).Contains(y.Id))
            .Select(y => y.Value);

    return queryA.Select(x => x.Value).Concat(queryB);
}

private static void Main(string[] args)
{
    var sourceA = new List<Foo>() {new Foo() {Context = 2, Data = "I'm a Foo"}};
    var sourceB = new List<Bar>() {new Bar() {Context = 2, Data = "I'm a Bar"}};

    var Output1 = sourceA.AsQueryable();
    var Output2 = sourceB.AsQueryable();

    var results = JoinTwoModels(
        Output1,
        Output2,
        (Func<Foo, int>) (x => x.Context),
        (Func<Bar, int>) (x => x.Context),
        (Func<Foo, string>) (x => x.Data),
        (Func<Bar, string>) (x => x.Data));

    foreach (var item in results)
        Console.WriteLine(item);
}

あなたが求めていたものは明確ではありませんでした。そのため、上記では、共通のコンテキスト (id) を共有する Source-A (Foo 型) と Source-B (Bar 型) からすべての項目を選択し、それらを変換された共通型で返しています。

bから次の値のみが必要な場合は、これを単純化できます。

var queryA = sourceA.Select(idSelectorA);

var queryB = sourceB
        .Select(y => new {Value = selectorB(y),Id = idSelectorB(y)})
        .Where(y => queryA.Select(x => x).Contains(y.Id))
        .Select(y => y.Value);

return queryB;
于 2013-02-27T18:03:07.360 に答える