C# 从SourceB获取SourceA中ID为的任何元素

C# 从SourceB获取SourceA中ID为的任何元素,c#,asp.net,linq,entity-framework,lambda,C#,Asp.net,Linq,Entity Framework,Lambda,我一直在尝试为两个不同数据库中的两个模型构建一种看似奇怪的连接方法,您可以查询第一个模型,然后返回一个小的id列表以在另一个数据库中搜索。除了一两件事之外,一切都正常,我不能使用lambda函数执行Id列表子查询,我有一个Id选择器函数,它链接了泛型,但在where子句中,它现在可以工作了,因为我不知道谁可以将源类型对象链接到Id的传递函数,所以.where(TSource=>idlist.Contains)(Idselector)示例代码如下所示,由于列表的原因,示例代码出现了中断。Conat

我一直在尝试为两个不同数据库中的两个模型构建一种看似奇怪的连接方法,您可以查询第一个模型,然后返回一个小的id列表以在另一个数据库中搜索。除了一两件事之外,一切都正常,我不能使用lambda函数执行Id列表子查询,我有一个Id选择器函数,它链接了泛型,但在where子句中,它现在可以工作了,因为我不知道谁可以将源类型对象链接到Id的传递函数,所以
.where(TSource=>idlist.Contains)(Idselector)
示例代码如下所示,由于
列表的原因,示例代码出现了中断。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();
公共静态Foo JoinTwoModels(
DbSet Dbs1,
DbSet Dbs2,
表达式Id1,
表达式选择器1,
表达式搜索1,
表达式Id2,
表达式选择器(2)
{
var Output1=可查询的类型(Dbs1);
var Output2=可查询的类型(Dbs2);
List Result1=Output1.Where(Search1).Select(Selector1.ToList();
List idList=new List();
PropertyInfo p1=Result1[0].GetType().GetProperty(“Id”);
foreach(结果1中的var o1)
{
idList.Add(p1.GetValue(o1));
}
//将结果条目查询到数据库中
List Result2=Output2.Where(idlist.contains(Id2)).ToList();

像这样的东西怎么样:

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);
}

感谢您的回复和帮助David,您是正确的,我希望在Id上将两个结果合并在一起,但我希望每次都能灵活地选择多个/不同的字段。因此,动态函数返回,我只是中间值,所以不确定,但您是固定到类的固定值/Id属性,还是动态的数字字段返回ed?这似乎也是linq to object IEnumerable查询,这对IQueryable to DB是否同样有效?再一次感谢,IEnumerable在迭代结果之前不会运行;因此我认为在IQueryable上运行IEnumerable是安全的(尽管我从未尝试过)。至于动态;动态将问题从编译时转移到运行时。我会尽量避免它,并使用强类型…Foo、T1、T2和TOutput可以是任何内容。但我认为您的数据库将有两列,ID和VALUE,并且值的类型不会随行而改变。也不要混淆两个问题;使用匹配项获取值ID;将作为IEnumerable返回…将其转换为查询并在其上运行数据字段选择。例如,您可以将T1和T2作为IQueryable。等等…谢谢,我有多个值/字段要返回(并动态选择)来自每一个源代码,但可以理解,在运行时使用动态和调试并不是上帝的做法。在返回整个对象数据集的查询上,在选择的几个字段上运行我的数据字段选择是否对性能有好处?很抱歉问了这么多问题,您已经帮了大忙是的,这一位是quearyA.select(x=>x)。Contains(y.Id)每次都将在databaseA上运行查询。如果您将其拉出并解析,它将只运行一次。即..ToList()。但现在,您正在解析其他内容中的查询。因此,请将其分解。一个方法不能同时完成两件事。
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;