1

我一直在尝试为两个不同数据库中的两个模型构建一个看起来很奇怪的连接方法,您可以查询第一个,然后返回一个小的 id 列表以在另一个数据库中搜索。一切正常,除了一两件事,我无法使用 lambda 函数执行 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);
}

你想要的不是很清楚;所以在上面,我从 Source-A(Foo 类型)和 Source-B(Bar 类型)中选择共享一个公共上下文(id)的所有项目,并以转换后的公共类型返回它们。

如果您只想要 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 回答