// ############ // RETURN TWO LIST<STRING> // ############ async void MultipleReturnsTest() { // Each IDriver instance maintains a pool of connections inside, as a result, it is recommended to only use one driver per application. // The driver is thread-safe, while the session or the transaction is not thread-safe. IDriver driver = GraphDatabase.Driver("neo4j://localhost:7687", AuthTokens.Basic("neo4j", "123456")); IAsyncSession session = driver.AsyncSession(o => o.WithDatabase("neo4j")); try { IResultCursor cursor = await session.RunAsync("MATCH (a:Person) RETURN a.name, a.born"); // A record is accessible once it is received by the client. It is not needed for the whole result set to be received before it can be visited. // Each record can only be visited (a.k.a.consumed) once! // The recommended way to access these result records is to make use of methods provided by ResultCursorExtensions such as SingleAsync, // ToListAsync, and ForEachAsync. List <DataHolder> people = await cursor.ToListAsync(record => new DataHolder(record["a.name"].As <string>(), record["a.born"].As <string>())); await cursor.ConsumeAsync(); foreach (var item in people) { Debug.Log(item.ToString()); } } finally { await session.CloseAsync(); } await driver.CloseAsync(); }
public async Task <List <T> > Run <T>(IQuery <T>[] queries, string databaseName, bool defaultDatabase) { IAsyncSession session = GetAsyncSession(databaseName, defaultDatabase); try { LogRun("queries", databaseName, defaultDatabase); var resultToReturn = new List <T>(); foreach (var query in queries) { await session.ReadTransactionAsync(async tx => { IResultCursor result = await tx.RunAsync(query.Query); resultToReturn.AddRange(await result.ToListAsync(query.ProcessRecord)); }); } return(resultToReturn); } finally { await session.CloseAsync(); } }
// ############ // RETURN SINGLE LIST<STRING> // ############ async void SingleReturnTest() { // Each IDriver instance maintains a pool of connections inside, as a result, it is recommended to only use one driver per application. // The driver is thread-safe, while the session or the transaction is not thread-safe. IDriver driver = GraphDatabase.Driver("neo4j://localhost:7687", AuthTokens.Basic("neo4j", "123456")); IAsyncSession session = driver.AsyncSession(o => o.WithDatabase("neo4j")); try { IResultCursor cursor = await session.RunAsync("MATCH (a:Person) RETURN a.name as name"); // The recommended way to access these result records is to make use of methods provided by ResultCursorExtensions such as SingleAsync, // ToListAsync, and ForEachAsync. List <string> people = await cursor.ToListAsync(record => record["name"].As <string>()); await cursor.ConsumeAsync(); Debug.Log(people.Count + " single returns"); } finally { await session.CloseAsync(); } await driver.CloseAsync(); }
// Get all records as a List public async Task <List <T> > FetchRecords <T>( Func <IRecord, T> recordProcessor, string cypherQuery, object queryParams = null) { List <T> result = null; IAsyncSession session = _driver.AsyncSession(o => o.WithDatabase(this._database)); _logger.LogDebug($"Executing query: {cypherQuery}"); if (queryParams == null) { queryParams = new {}; } try { IResultCursor resultCursor = await session.RunAsync(cypherQuery, queryParams); result = await resultCursor.ToListAsync(record => recordProcessor(record)); _logger.LogDebug("Query executed successfully"); } catch (Exception ex) { _logger.LogError(ex, $"Error executing query. {ex.Message}"); throw; } finally { await session.CloseAsync(); } return(result); }
public async Task ShouldThrowExceptionIfNullResult() { IResultCursor result = null; var exception = await Record.ExceptionAsync(() => result.ToListAsync()); exception.Should().BeOfType <ArgumentNullException>(); }
private static async Task AssertCannotAccessRecords(IResultCursor cursor) { await ThrowsResultConsumedException(async() => await cursor.FetchAsync()); await ThrowsResultConsumedException(async() => await cursor.PeekAsync()); ThrowsResultConsumedException(() => cursor.Current); await ThrowsResultConsumedException(async() => await cursor.SingleAsync()); await ThrowsResultConsumedException(async() => await cursor.ToListAsync()); await ThrowsResultConsumedException(async() => await cursor.ForEachAsync(r => { })); }
#pragma warning disable S4144 //todo: read/write? can't seems to specify with BeginTransactionAsync? could have 1 read & 1 write transaction? specify write at the session level? remove distinction and just have RunQuery? public async Task <List <T> > RunWriteQuery <T>(Query query, Func <IRecord, T> operation) { if (_transaction == null) { throw new InvalidOperationException($"{nameof(GraphDatabaseTestRun)} not initialised."); } IResultCursor result = await _transaction.RunAsync(query); return(await result.ToListAsync(operation)); }
public async Task ProcurarFamilia(string filho, string aniFilho, bool comAnilha) //Testar essa função { session = _driver.AsyncSession(o => o.WithDatabase("neo4j")); //Nome da database está nas propriedades como padrão try { string optMatch; string matchf; if (comAnilha) { matchf = "MATCH (f:Passaro{nome:$filho, anilha:$aniFilho})" + "OPTIONAL MATCH (f)<-[:PAI]-(p1:Passaro)" + "OPTIONAL MATCH (m1:Passaro)-[:MAE]->(f)"; } else { matchf = "MATCH (f:Passaro{nome:$filho})" + "WHERE ID(f) = toInteger($aniFilho)" + "OPTIONAL MATCH (f)<-[:PAI]-(p1:Passaro)" + "OPTIONAL MATCH (m1:Passaro)-[:MAE]->(f)"; } optMatch = "optional match(m2:Passaro)-[:MAE]->(p1) < -[:PAI] - (p2: Passaro)" + "optional match(m3:Passaro)-[:MAE]->(m1) < -[:PAI] - (p3: Passaro)" + "optional match(m4:Passaro)-[:MAE]->(p2) < -[:PAI] - (p4: Passaro)" + "optional match(m5:Passaro)-[:MAE]->(m2) < -[:PAI] - (p5: Passaro)" + "optional match(m6:Passaro)-[:MAE]->(p3) < -[:PAI] - (p6: Passaro)" + "optional match(m7:Passaro)-[:MAE]->(m3) < -[:PAI] - (p7: Passaro)" + "OPTIONAL MATCH(m8:Passaro)-[:MAE]->(p4) < -[:PAI] - (p8: Passaro)" + "OPTIONAL MATCH(m9:Passaro)-[:MAE]->(m4) < -[:PAI] - (p9: Passaro)" + "OPTIONAL MATCH(m10:Passaro)-[:MAE]->(p5) < -[:PAI] - (p10: Passaro)" + "OPTIONAL MATCH(m11:Passaro)-[:MAE]->(m5) < -[:PAI] - (p11: Passaro)" + "OPTIONAL MATCH(m12:Passaro)-[:MAE]->(p6) < -[:PAI] - (p12: Passaro)" + "OPTIONAL MATCH(m13:Passaro)-[:MAE]->(m6) < -[:PAI] - (p13: Passaro)" + "OPTIONAL MATCH(m14:Passaro)-[:MAE]->(p7) < -[:PAI] - (p14: Passaro)" + "OPTIONAL MATCH(m15:Passaro)-[:MAE]->(m7) < -[:PAI] - (p15: Passaro)" + "return [f.nome, p1.nome, m1.nome, p2.nome, m2.nome, p3.nome, m3.nome, " + "p4.nome, m4.nome, p5.nome, m5.nome, p6.nome, m6.nome, p7.nome, m7.nome," + "p8.nome, m8.nome, p9.nome, m9.nome, p10.nome, m10.nome, p11.nome, m11.nome," + "p12.nome, m12.nome, p13.nome, m13.nome, p14.nome, m14.nome, p15.nome, m15.nome] AS familia"; cursor = await session.RunAsync(matchf + optMatch, new { filho, aniFilho }); records = await cursor.ToListAsync(); familia = new List <string>(); //familia.Add(aniFilho); //familia.Add(filho); familia = Records(); resultado = await cursor.ConsumeAsync(); } finally { await session.CloseAsync(); } }
private async Task <object> GetListOfRecordsAsync() { var records = await _resultCursor.ToListAsync(); if (records == null || !records.Any()) { return(null); } var neoRecords = records.SelectMany(x => x.Values.Values); return(neoRecords.FirstOrDefault()); }
private async Task ExecuteCypher(string cypherQuery) { ExecuteQueryArgs e; var session = _driver.AsyncSession(); try { if (_connected == false) { var control = _customTaskPane.Control as ExecuteQuery; ConnectDatabase(this, new ConnectDatabaseArgs { ConnectionString = control.ConnectionString() }); } var worksheet = ((Worksheet)Application.ActiveSheet); try { IResultCursor cursor = await session.RunAsync(cypherQuery); var records = await cursor.ToListAsync(); LoadRowsFromRecords(records, worksheet); var summary = await cursor.ConsumeAsync(); string summaryText = summary.ToString(); CurrentControl.SetMessage("Execution Summary :" + "\n\n" + summaryText); } finally { await session.CloseAsync(); } } catch (Neo4jException ex) { CurrentControl.SetMessage(ex.Message); } finally { await session.CloseAsync(); } }
public async Task <List <IRecord> > ProcurarPais(string nome, string anilha, bool comAnilha) { session = _driver.AsyncSession(o => o.WithDatabase("neo4j"));//Nome da database está nas propriedades como padrão try { if (!comAnilha) { if (anilha != String.Empty) { cursor = await session.RunAsync("MATCH (f:Passaro{nome:$nome})" + "WHERE ID(f) = toInteger($anilha) " + "OPTIONAL MATCH (m1:Passaro)-[:MAE]->(f)" + "OPTIONAL MATCH (f)<-[:PAI]-(p1:Passaro)" + "RETURN f,[f.nome] AS Nomes,[m1.nome] AS Maes,[p1.nome] AS Pais, [ID(f)] AS Ids", new { nome, anilha }); } else { cursor = await session.RunAsync("MATCH (f:Passaro{nome:$nome})" + "OPTIONAL MATCH (m1:Passaro)-[:MAE]->(f)" + "OPTIONAL MATCH (f)<-[:PAI]-(p1:Passaro)" + "RETURN f,[f.nome] AS Nomes,[m1.nome] AS Maes,[p1.nome] AS Pais, [ID(f)] AS Ids", new { nome }); } } else { cursor = await session.RunAsync("MATCH (f:Passaro {nome: $nome, anilha:$anilha})" + "OPTIONAL MATCH (m1:Passaro)-[:MAE]->(f)" + "OPTIONAL MATCH (f)<-[:PAI]-(p1:Passaro)" + "RETURN f,[f.nome] AS Nomes,[m1.nome] AS Maes,[p1.nome] AS Pais, [ID(f)] AS Ids", new { nome, anilha }); } var lista = await cursor.ToListAsync(); resultado = await cursor.ConsumeAsync(); return(lista); } finally { await session.CloseAsync(); } }
private async void ExecuteCypher(object sender, ExecuteQueryArgs e) { var session = _driver.AsyncSession(); try { if (_connected == false) { var control = _customTaskPane.Control as ExecuteQuery; ConnectDatabase(this, new ConnectDatabaseArgs { ConnectionString = control.ConnectionString() }); } var worksheet = ((Worksheet)Application.ActiveSheet); try { IResultCursor cursor = await session.RunAsync(e.Cypher); var records = await cursor.ToListAsync(); var summary = await cursor.ConsumeAsync(); string message = summary.ToString(); CurrentControl.SetMessage(message); } finally { await session.CloseAsync(); } } catch (Neo4jException ex) { CurrentControl.SetMessage(ex.Message); } finally { await session.CloseAsync(); } }
//TODO: Mudar cor das labels na frente do cartão pelo usuário //TODO: Menu para atualizar campos de passarinho //TODO: Pontos que precisam estão marcados com indicadores de bandeira branca //TODO: Clicar em pesquisar sem sair nomeFilhoF faz com que listnomesF == null //TODO: Criar menu para cadastrar em árvore //TODO: Atualizar buttonPesquisa para buttonImpressão public async Task <List <IRecord> > ProcurarFilhos(string nome) { session = _driver.AsyncSession(o => o.WithDatabase("neo4j"));//Nome da database está nas propriedades como padrão try { cursor = await session.RunAsync("MATCH (p:Passaro {nome: $nome})" + "OPTIONAL MATCH (p)-[:PAI|MAE]->(f:Passaro)" + "RETURN [p.nome] AS Nomes, [ID(p)] AS Ids,[f.nome] AS Filhos, " + "[p.anilha] AS Anilhas, [p.Sexo] AS Sexos, [p.NomePopular] AS NomesPopulares, " + "[p.Nascimento] AS Nascimentos ", new { nome }); var lista = await cursor.ToListAsync(); resultado = await cursor.ConsumeAsync(); return(lista); } finally { await session.CloseAsync(); } }
public async Task Run(ICommand[] commands, string databaseName, bool defaultDatabase) { IAsyncSession session = GetAsyncSession(databaseName, defaultDatabase); try { // transaction functions auto-retry //todo: configure retry? timeout? etc. LogRun("command(s)", databaseName, defaultDatabase); await session.WriteTransactionAsync(async tx => { foreach (ICommand command in commands) { IResultCursor result = await tx.RunAsync(command.Query); var records = await result.ToListAsync(r => r); var resultSummary = await result.ConsumeAsync(); _logger.LogDebug("Query result available after: {ResultAvailableAfter}, consumed after: {ResultConsumedAfter}", resultSummary.ResultAvailableAfter, resultSummary.ResultConsumedAfter); if (resultSummary.Notifications.Any()) { _logger.LogWarning($"Query had notifications{Environment.NewLine}:{string.Join(Environment.NewLine, resultSummary.Notifications)}"); } command.ValidateResults(records, resultSummary); } }); } finally { await session.CloseAsync(); } }
private async void CreateRelationships(object sender, SelectionArgs e) { if (_connected == false) { var control = _customTaskPane.Control as ExecuteQuery; ConnectDatabase(this, new ConnectDatabaseArgs { ConnectionString = control.ConnectionString() }); } var session = _driver.AsyncSession(); try { var worksheet = ((Worksheet)Application.ActiveSheet); var inputrange = e.SelectionRange; if (inputrange.Columns.Count <= 1) { CurrentControl.SetMessage("Select 3 columns with nodes and relationship to create"); await session.CloseAsync(); return; } if (inputrange.Rows.Count <= 2) { CurrentControl.SetMessage("Select 2 header rows and 1 data row"); await session.CloseAsync(); return; } string label1 = Convert.ToString(inputrange.Cells[1, 1].Value2); string label2 = Convert.ToString(inputrange.Cells[1, 2].Value2); string relationshiptype = Convert.ToString(inputrange.Cells[1, 3].Value2); if (label1.Length == 0 || label2.Length == 0 || relationshiptype.Length == 0) { CurrentControl.SetMessage("Labels and relationship type must not be empty"); await session.CloseAsync(); return; } string[] properties = new string[inputrange.Columns.Count]; for (int i = 1; i <= inputrange.Columns.Count; i++) { try { properties[i - 1] = Convert.ToString(inputrange.Cells[2, i].Value2); } catch { } } for (int r = 3; r <= inputrange.Rows.Count; r++) { var row = inputrange.Rows[r]; var input = inputrange; string cypher = "MATCH (a: {0}),(b: {1} ) WHERE a.`{2}` = '{3}' and b.`{4}` = '{5}' MERGE (a)-[r:`{6}`]->(b) {7}"; string relprop = ""; if (properties.Length > 2) { relprop = "SET r += { "; bool addcoma = false; for (int p = 2; p < properties.Length; p++) { string propvalue = Convert.ToString(inputrange.Cells[r, p].Value2); if (properties[p].Length > 0 && propvalue.Length > 0) { string prop = "`{0}`:\"{1}\""; prop = String.Format(prop, properties[p], propvalue); if (addcoma) { relprop += " , "; } addcoma = true; relprop += prop; } } relprop += " }"; if (relprop.Length == "SET r += { ".Length) { relprop = ""; } } string formatedcypher = String.Format( cypher, label1, label2, properties[0], inputrange.Cells[r, 1].Value2.ToString(), properties[1], inputrange.Cells[r, 2].Value2.ToString(), relationshiptype, relprop); try { IResultCursor cursor = await session.RunAsync(formatedcypher); var records = await cursor.ToListAsync(); var summary = await cursor.ConsumeAsync(); if (r == inputrange.Rows.Count) { string message = summary.ToString(); CurrentControl.SetMessage(message); } } catch (Exception ex) { CurrentControl.SetMessage(ex.Message); } } await session.CloseAsync(); } catch (Neo4jException ex) { CurrentControl.SetMessage(ex.Message); } }
private async void CreateNodes(object sender, SelectionArgs e) { var control = _customTaskPane.Control as ExecuteQuery; if (_connected == false) { ConnectDatabase(this, new ConnectDatabaseArgs { ConnectionString = control.ConnectionString() }); } var session = _driver.AsyncSession(); try { var worksheet = ((Worksheet)Application.ActiveSheet); var inputrange = e.SelectionRange; control.progress.Report(0); if (inputrange.Columns.Count <= 1) { CurrentControl.SetMessage("Select more than 1 column"); } string[] properties = new string[inputrange.Columns.Count]; for (int i = 2; i <= inputrange.Columns.Count; i++) { try { properties[i - 2] = Convert.ToString(inputrange.Cells[1, i].Value2); } catch { properties[i - 2] = "property" + (i - 1).ToString(); } } for (int r = 2; r <= inputrange.Rows.Count; r++) { control.progress.Report(r / inputrange.Rows.Count * 100); var row = inputrange.Rows[r]; var label = ""; try { label = row.Cells[1, 1].Value2.ToString(); } catch { label = "NewExcelNode"; } string cypher = "MERGE (a: " + label + " { "; int i = 2; { string propval = Convert.ToString(row.Cells[1, i].Value2); if (properties[i - 2].Length > 0 && propval.Length > 0) { cypher += "`" + properties[i - 2] + "`" + ": \"" + propval + "\","; } } cypher = cypher.TrimEnd(','); cypher += "})"; if (row.columns.count > 2) { cypher += " SET a += { "; for (i = 3; i <= row.Columns.Count; i++) { string propval = Convert.ToString(row.Cells[1, i].Value2); if (properties[i - 2] != null && propval != null) { if (properties[i - 2].Length > 0 && propval.Length > 0) { cypher += "`" + properties[i - 2] + "`" + ": \"" + propval + "\","; } } } cypher = cypher.TrimEnd(','); cypher += "}"; } try { IResultCursor cursor = await session.RunAsync(cypher); var records = await cursor.ToListAsync(); var summary = await cursor.ConsumeAsync(); string message = summary.ToString(); if (r == inputrange.Rows.Count) { CurrentControl.SetMessage(message); } } catch (Neo4jException ee) { CurrentControl.SetMessage(ee.Message); } } await session.CloseAsync(); } catch (Neo4jException ex) { CurrentControl.SetMessage(ex.Message); } }
private async void UpdateActiveWorksheet(object sender, SelectionArgs e) { var control = _customTaskPane.Control as ExecuteQuery; if (_connected == false) { ConnectDatabase(this, new ConnectDatabaseArgs { ConnectionString = control.ConnectionString() }); } var session = _driver.AsyncSession(); try { var worksheet = ((Worksheet)Application.ActiveSheet); var inputrange = e.SelectionRange; inputrange = worksheet.UsedRange; int indexOfIdentifier = 0; control.progress.Report(0); if (inputrange.Columns.Count <= 1) { CurrentControl.SetMessage("Select more than 1 column"); } string[] properties = new string[inputrange.Columns.Count]; for (int i = 0; i < inputrange.Columns.Count; i++) { int excelIndex = i + 1; try { string colName = Convert.ToString(inputrange.Cells[1, excelIndex].Value2); properties[i] = colName; string s = colName.ToLowerInvariant(); if (s == "uuid") { indexOfIdentifier = i; } } catch { properties[i - 2] = "property" + (i - 1).ToString(); } } for (int r = 2; r <= inputrange.Rows.Count; r++) { control.progress.Report(r / inputrange.Rows.Count * 100); var row = inputrange.Rows[r]; var label = ""; try { label = row.Cells[1, 1].Value2.ToString(); label = worksheet.Name; } catch { label = "NewExcelNode"; } string cypher = "MERGE (a: " + label + " { "; { cypher += GetIdentifierPropertyValue(row, properties, indexOfIdentifier); } cypher = cypher.TrimEnd(','); cypher += "})"; // check if worksheet have 1 property column + 1 data column if (row.columns.count > 1) { cypher += " SET a += { "; for (int i = 0; i < row.Columns.Count; i++) { int excelIndex = i + 1; // Skip first record as it is used in Merge identifier. if (i == indexOfIdentifier) { continue; } string secondRecordValue = Convert.ToString(row.Cells[1, excelIndex].Value2); if (properties[i] != null && secondRecordValue != null) { if (properties[i].Length > 0 && secondRecordValue.Length > 0) { cypher += "`" + properties[i] + "`" + ": \"" + secondRecordValue + "\","; } } } cypher = cypher.TrimEnd(','); cypher += "}"; } try { IResultCursor cursor = await session.RunAsync(cypher); var records = await cursor.ToListAsync(); var summary = await cursor.ConsumeAsync(); string message = summary.ToString(); if (r == inputrange.Rows.Count) { CurrentControl.SetMessage(message); } } catch (Neo4jException ee) { CurrentControl.SetMessage(ee.Message); } } await session.CloseAsync(); } catch (Neo4jException ex) { CurrentControl.SetMessage(ex.Message); } }
public async Task <IEnumerable <LiveDbObject <T> > > ReturnAsync() { internalQ.Append("WITH "); for (int i = 0; i < PathCount; i++) { if (i > 0) { internalQ.Append(" + "); } internalQ.Append($"collect(p{i})"); } internalQ.Append($" AS paths{Environment.NewLine}"); internalQ.Append($"UNWIND paths AS ret{Environment.NewLine}"); internalQ = internalQ.AppendLine("RETURN ret as json"); using (IDriver driver = clientFactory()) { Query q = new Query(internalQ.ToString()); IResultCursor resultCursor = await driver.AsyncSession().RunAsync(q); List <IRecord> results = await resultCursor.ToListAsync(); Dictionary <string, INeo4jNode> nodeHeap = new Dictionary <string, INeo4jNode>(); var raw = results.SelectMany(x => { var h = x["json"].As <IPath>(); List <INeo4jNode> nodes = h.Nodes.Select(a => { INeo4jNode parentInstance; if (!nodeHeap.TryGetValue(a["Id"].ToString(), out parentInstance)) { Type parentType = ReflectionCache.BuildType(a["__type__"].As <string>()); parentInstance = Activator.CreateInstance(parentType) as INeo4jNode; ReflectionCache.Type typeData = ReflectionCache.GetTypeData(parentType); foreach (KeyValuePair <string, object> k in a.Properties) { if (typeData.props.TryGetValue(k.Key, out ReflectionCache.Property prop)) { prop.PushValue(parentInstance, DBOps.Neo4jDecode(k.Value, prop.info.PropertyType)); } } nodeHeap.Add(a["Id"].ToString(), parentInstance); } return(parentInstance); }).ToList(); return(h.Relationships .Select((x, i) => (nodes[i].Id, nodes[i + 1].Id, x.Type)) .Cast <(string parentID, string childID, string relationship)>()); }).ToList(); var withProps = raw.Select(x => (x.Item1, x.Item2, ReflectionCache.GetTypeData(nodeHeap[x.Item1]).props .Where(y => y.Key == x.Item3 || ( y.Value.neo4JAttributes.Where(x => x is DbNameAttribute).Any() && y.Value.neo4JAttributes.Select(x => x as DbNameAttribute).Where(x => x != null).FirstOrDefault()?.Name == x.Item3 ) ) .SingleOrDefault() .Value )).ToList(); var groupDedupe = withProps.GroupBy(x => x.Item1 + x.Item2).Select(x => x.First()).GroupBy(x => (x.Value, x.Item1)); foreach (var g in groupDedupe) { if (!g.Key.Value.isCollection) { var v = g.Single(); v.Item3.PushValue(nodeHeap[v.Item1], nodeHeap[v.Item2]); } else { System.Type t = g.Key.Value.info.PropertyType.GetGenericArguments()[0]; System.Type lstT = typeof(List <>).MakeGenericType(t); ConstructorInfo cotr = lstT.GetConstructors().Where(x => x.GetParameters().Length == 0).Single(); Type enu = typeof(Enumerable); MethodInfo selct = enu.GetMethods() .Where(x => x.Name == "Select") .OrderBy(x => x.GetParameters().Length) .First() .MakeGenericMethod(typeof(string), t); MethodInfo toLst = enu.GetMethods() .Where(x => x.Name == "ToList") .OrderBy(x => x.GetParameters().Length) .First() .MakeGenericMethod(t); Type ndhpTyp = nodeHeap.GetType(); ParameterExpression ndhp = Expression.Parameter(ndhpTyp, "ndhp"); ParameterExpression ky = Expression.Parameter(typeof(string), "ky"); var selExpr = Expression.Lambda( Expression.Convert(Expression.Property(ndhp, "Item", ky), t), ky ); var expr = Expression.Lambda( Expression.Call( null, toLst, Expression.Call( null, selct, Expression.Constant(g.Select(x => x.Item2)), selExpr ) ), ndhp ); object psh = expr.Compile().DynamicInvoke(nodeHeap); g.Key.Item1.PushValue(nodeHeap[g.Key.Item2], psh); } } var ret = nodeHeap .Select(x => x.Value) .Where(x => x is T) .Cast <T>() .Distinct() .Select(x => LiveDbObject <T> .Build(x, clientFactory, LiveObjectMode.LiveWrite | LiveObjectMode.DeferedRead)) .ToArray(); return(ret); } }