Create a Lambda Expression having a WHERE IN Clause - c#

I want to create a lambda expression dynamically for this:
List<Coverage>? excludedCoverage = originalCoverage.Where(a => currentCoverage.Select(k => k.CoverageId).Contains(a.CoverageId) == false).ToList();
I have this two lists:
var originalCoverage = new List<Coverage>() {
new Coverage { CoverageId = 1, Name = "Name 1", },
new Coverage { CoverageId = 2, Name = "Name 2", },
new Coverage { CoverageId = 3, Name = "Name 3", },
new Coverage { CoverageId = 4, Name = "Name 4", },
new Coverage { CoverageId = 5, Name = "Name 5", },
};
var currentCoverage = new List<Coverage>() {
new Coverage { CoverageId = 4, Name = "Name 4", },
new Coverage { CoverageId = 5, Name = "Name 5", },
};
I have the following codes which work for a basic WHERE clause:
var parameterExpression = Expression.Parameter(typeof(Coverage), "a");
var property = Expression.Property(parameterExpression, "CoverageId");
var expression = Expression.Equal(property, Expression.Constant(0));
var lambda = Expression.Lambda<Func<Coverage, bool>>(expression, parameterExpression);
var createLamda = lambda.Compile();
var newDatas = currentCoverage?.Where(createLamda).ToList();
How can I write an the WHERE IN clause using dynamic lambda expression?
List<Coverage>? excludedCoverage = originalCoverage.Where(a => currentCoverage.Select(k => k.CoverageId).Contains(a.CoverageId) == false).ToList();
Thanks

Related

Mapping of nested IEnumerable<IDictionary> to a different type of nested IEnumerable<IDictionary>

I need to do some "weird" mapping and I've tried a lot of things without getting even close, so I'm not sure if it's possible or not.
I have this "rowDefinition": this is like a contract of how the data in the end should looks like, "1A" and stuff are ID's of data that I'll get from a service
var rowDefinitions = new Dictionary<string, IEnumerable<IDictionary<string, object>>>
{
["Managers"] = new List<IDictionary<string, object>>
{
new Dictionary<string, object>
{
["MANAGER_NAME"] = "1A",
["WEBSITE"] = "3A",
["NIP"] = "4A",
["AUM"] = "5A"
}
},
["Funds"] = new List<IDictionary<string, object>>
{
new Dictionary<string, object>
{
["FUND_NAME"] = "6A",
["CURRENCY"] = "2A",
}
}
};
And I have this data coming from a service like this, each one of the Dictionaries represents kind of a row for the above structure
var dataFromService = new List<IDictionary<string, object>>
{
new Dictionary<string, object>
{
["1A"] = "manager name 1",
["3A"] = "website 1",
["4A"] = "ni professionals 1",
["5A"] = "aum 1"
},
new Dictionary<string, object>
{
["1A"] = "manager name 2",
["3A"] = "website 2",
["4A"] = "other ni professional 2",
["5A"] = "one more aum 2"
},
new Dictionary<string, object>
{
["6A"] = "fund name 4",
["2A"] = "currecy 4",
},
new Dictionary<string, object>
{
["6A"] = "fund name 5",
["2A"] = "currecy 5",
},
new Dictionary<string, object>
{
["6A"] = "fund name 6",
["2A"] = "currecy 6",
},
};
I need to map this data according to the "rowDefinition" and get something like this
var expectedResult = new Dictionary<string, IEnumerable<IDictionary<string, object>>>
{
["Managers"] = new List<IDictionary<string, object>>
{
new Dictionary<string, object>
{
["MANAGER_NAME"] = "manager name 1",
["WEBSITE"] = "website 1",
["NIP"] = "ni professionals 1",
["AUM"] = "aum 1"
},
new Dictionary<string, object>
{
["MANAGER_NAME"] = "manager name 2",
["WEBSITE"] = "website 2",
["NIP"] = "other ni professional 2",
["AUM"] = "one more aum 2"
}
},
["Funds"] = new List<IDictionary<string, object>>
{
new Dictionary<string, object>
{
["FUND_NAME"] = "fund name 4",
["CURRENCY"] = "currency 4"
},
new Dictionary<string, object>
{
["FUND_NAME"] = "fund name 5",
["CURRENCY"] = "currency 5"
},
new Dictionary<string, object>
{
["FUND_NAME"] = "fund name 6",
["CURRENCY"] = "currency 6"
}
}
};
RowDefinitions inside ["Managers"] or ["Funds"] can have more key-value pairs and there can be something else as ["Potato"], in short terms, I should be able to modify rowDefinitions and of course the date I'll get back will include the respective info
This sort of does the job, but looks pretty ugly (and definitely not efficient), I think this can be done with LINQ, but don't know how
private void UglyWay(List<IDictionary<string, object>> dataScopeWithDataPoints, IDictionary<string, IEnumerable<IDictionary<string, object>>> rowDefinitions)
{
var excelData = new Dictionary<string, List<IDictionary<string, object>>>();
foreach (var dataScope in dataScopeWithDataPoints)
{
foreach (var excelRowDefinition in rowDefinitions)
{
var rowDefinition = excelRowDefinition.Value.First();
var row = new Dictionary<string, object>();
var found = false;
foreach (var dataPoint in rowDefinition)
{
if (dataScope.ContainsKey(dataPoint.Value.ToString()))
{
row[dataPoint.Key] = dataScope[dataPoint.Value.ToString()];
found = true;
}
}
if (found)
{
if (!excelData.ContainsKey(excelRowDefinition.Key))
{
excelData[excelRowDefinition.Key] = new List<IDictionary<string, object>>();
}
excelData[excelRowDefinition.Key].Add(row);
}
}
}
return;
}
If you need any extra information, please just let me know.
Using the row definition, put in a more usable format, you can extract each matching data dictionary and remap:
var ans = rowDefinitions.Select(rd => new { rd.Key, Definition = rd.Value.First().Select(kv => new { kv.Key, Value = kv.Value.ToString() }) })
.ToDictionary(rd => rd.Key,
rd => dataFromService.Where(d => d.ContainsKey(rd.Definition.First().Value))
.Select(d => rd.Definition.ToDictionary(def => def.Key, def => d[def.Value]))
.ToList()
);
NOTE: This creates Dictionary<string, List<Dictionary<string, object>>> instead of Dictionary<string, IEnumerable<IDictionary<string, object>>>. If you really need the IDictionary and IEnumerable, you can cast the value created from dataFromService and convert the List<>.
Here is that code:
var ans = rowDefinitions.Select(rd => new { rd.Key, Definition = rd.Value.First().Select(kv => new { kv.Key, Value = kv.Value.ToString() }) })
.ToDictionary(rd => rd.Key,
rd => dataFromService.Where(d => d.ContainsKey(rd.Definition.First().Value))
.Select(d => (IDictionary<string,object>)rd.Definition.ToDictionary(def => def.Key, def => d[def.Value]))
.ToList()
.AsEnumerable()
);
NOTE: Missing values in dataFromService will cause exceptions.
If it is possible for the row definitions to overlap, you can select the row definition that has all matching field names instead of just testing one:
var ans2 = rowDefinitions.Select(rd => new { rd.Key, Definition = rd.Value.First().Select(kv => new { kv.Key, Value = kv.Value.ToString() }).ToList() })
.ToDictionary(rd => rd.Key,
rd => dataFromService.Where(d => rd.Definition.Count == d.Keys.Count && rd.Definition.All(dkv => d.ContainsKey(dkv.Value)))
.Select(d => (IDictionary<string,object>)rd.Definition.ToDictionary(def => def.Key, def => d[def.Value]))
.ToList()
.AsEnumerable()
);

NetSuite Web API - How to return/populate customFieldList array for Sales Order from a joined search?

I am currently performing a SuiteTalk search via C# that joins multiple tables, one of which is for Sales Orders. When performing a typical GET on a SalesOrder record, the property customFieldList gets populated with an array of transaction custom fields/etc. I am curious how to get the same when doing a search like:
SearchResult searchResult = Client.Service.search(new TransactionSearchAdvanced()
{
criteria = new TransactionSearch()
{
basic = new TransactionSearchBasic()
{
type = new SearchEnumMultiSelectField()
{
#operator = SearchEnumMultiSelectFieldOperator.anyOf,
operatorSpecified = true,
searchValue = new String[] { "_salesOrder" },
},
lastModifiedDate = new SearchDateField()
{
#operator = SearchDateFieldOperator.after,
operatorSpecified = true,
searchValue = fromLastModifiedDateTime.ToUniversalTime(),
searchValueSpecified = true
}
},
},
columns = new TransactionSearchRow()
{
basic = new TransactionSearchRowBasic()
{
internalId = new SearchColumnSelectField[] { new SearchColumnSelectField() },
tranId = new SearchColumnStringField[] { new SearchColumnStringField() },
tranDate = new SearchColumnDateField[] { new SearchColumnDateField() },
dateCreated = new SearchColumnDateField[] { new SearchColumnDateField() },
item = new SearchColumnSelectField[] { new SearchColumnSelectField() },
quantity = new SearchColumnDoubleField[] { new SearchColumnDoubleField() },
lastModifiedDate = new SearchColumnDateField[] { new SearchColumnDateField() },
email = new SearchColumnStringField[] { new SearchColumnStringField() },
//customFieldList = new SearchColumnCustomField[] { },
},
itemJoin = new ItemSearchRowBasic()
{
itemId = new SearchColumnStringField[] { new SearchColumnStringField() },
type = new SearchColumnEnumSelectField[] { new SearchColumnEnumSelectField() },
},
customerJoin = new CustomerSearchRowBasic()
{
internalId = new SearchColumnSelectField[] { new SearchColumnSelectField() },
billAddress = new SearchColumnStringField[] { new SearchColumnStringField() },
companyName = new SearchColumnStringField[] { new SearchColumnStringField() },
phone = new SearchColumnStringField[] { new SearchColumnStringField() },
email = new SearchColumnStringField[] { new SearchColumnStringField() },
},
customSearchJoin = new CustomSearchRowBasic[]
{
},
}
});
The property I want populated is commented out within the TransactionSearchRowBasic object:
//customFieldList = new SearchColumnCustomField[] { },
Any ideas? Thank you in advance!
The search operation doesn't return as much information as a GET operation does on the SuiteTalk Web Services.
For each record that is returned in your SearchResult, use the internalId or document number to GET that record. This should then include your custom fields.
NetSuiteService _service = new NetSuiteService();
ReadResponse res = _service.get(new RecordRef { internalId = internalID, type = RecordType.salesOrder, typeSpecified = true });

give names to a var object in .net

just wondering I am using a web method to return some json data to a web form. anyway I don't want the entire class in json just two of the columns. so I used linq to get the columns here is an example.
IEnumerable<Person> model = new List<Person>
{
new Person { id = 1, Name = "Bryan", Phone = "218-0211", Email = "bryan#mail.mil" },
new Person { id = 2, Name = "Joe", Phone = "248-0241", Email = "joe#mail.mil" },
new Person { id = 3, Name = "Fred", Phone = "354-0441", Email = "fred#mail.mil" },
new Person { id = 4, Name = "Mary", Phone = "344-3451", Email = "mary#mail.mil" },
new Person { id = 5, Name = "Jill", Phone = "127-3451", Email = "jill#mail.mil" }
};
var mysubset = from a in model select new { a. Name, a.Email };
unfotunately when I then serialize my result and send it back I lose the column names. so data.name doesn't work so I was wondering can I give names to a var type? for example is there a way to do this?
var mysubset = from a in model select new { a. Name, a.Email };
string myname as string;
foreach (var item in mysubset)
{
myname = subset.Name;
}
ok here is the actual code sorry it is in vb but that is the project I inherited
Dim mycollection = From a in cmpnyList select {a.CmpnyName, a.ShipFrom}
return jsSerialize.Serialize(mycollection)
the json returned from that is
[{"Company A","New York"},{"Company B", "Harrisburg"}]
so I'm trying to get back something like
[{"CmpnyName":"Company A", "ShipFrom": "New York"},
{"CmpnyName": "Company B", "ShipFrom": "Harrisburg}]
I believe you're using json.net the answer would be something like this using jobject(newtonsoft.json.linq)
JObject o = new JObject(
new JProperty("PersonssList",
new JArray(
from p in model
select new JObject(
new JProperty("PersonName", p.Name),
new JProperty("Email", p.Email)))));
and the result would be this json
{
"PersonssList": [
{
"PersonName": "Bryan",
"Email": "bryan#mail.mil"
},
{
"PersonName": "Joe",
"Email": "joe#mail.mil"
},
{
"PersonName": "Fred",
"Email": "fred#mail.mil"
},
{
"PersonName": "Mary",
"Email": "mary#mail.mil"
},
{
"PersonName": "Jill",
"Email": "jill#mail.mil"
}
]

Concatenate multiple rows into a single row in LINQ

Is is possible to concatenate multiple rows to a single row?
for example:
IEnumerable<sample> sam = new List<sample>()
{
new sample{ id = 1, name = "sample 1", list = new List<int>{1,5,6}},
new sample{ id = 2, name = "sample 2", list = new List<int>{2,9}},
new sample{ id = 3, name = "sample 3", list = new List<int>{8,3,7}},
new sample{ id = 4, name = "sample 4", list = new List<int>{3,4,8}},
new sample{ id = 5, name = "sample 5", list = new List<int>{1,5,7}},
new sample{ id = 6, name = "sample 6", list = new List<int>{6,9,7}}
};
output must:
{
new sample { id = 1, name = "sample 1", list = "1,5,6" },
new sample { id = 2, name = "sample 2", list = "2,9" },
new sample { id = 3, name = "sample 3", list = "8,3,7" },
new sample { id = 4, name = "sample 4", list = "3,4,8" },
new sample { id = 5, name = "sample 5", list = "1,5,7" },
new sample { id = 6, name = "sample 6", list = "6,9,7" }
};
That means from list the new row is now a string.
Sure:
sam.Select(x => new { x.id, x.name, list = String.Join(",", x.list) });
Note: The result will be an anonymous type. We can't reuse the sample class here, because in that class list is of type List<int> and not string.
If you are stuck with .NET 3.5 or less, use this code instead:
sam.Select(x => new
{
x.id, x.name,
list = String.Join(",", x.list.Select(y => y.ToString())
.ToArray())
});
If you want to sort the list before getting the string you need to use this code:
sam.Select(x => new
{
x.id, x.name,
list = String.Join(",", x.list.OrderBy(y => y))
});
As I needed to gather several records in one column (each employee may have many specialties) and then use it in a join, this is the way I resolved:
Having these entities:
1) EMPLOYEEs Entity
|EMPLOYEE_ID|
|001 |
|002 |
2) EMPLOYEE_SPECIALTIES Entity
|EmployeeId|SPECIALTY_CODE
|001 |AAA
|001 |BBB
|002 |DDD
|002 |AAA
I needed to gather specialties by employee in one columun:
|EmployeeId|SPECIALTY_CODE
|001 |AAA, BBB
|002 |DDD, AAA
Solution:
var query = from a in context.EMPLOYEE_SPECIALTIES.ToList()
group a by a.EMPLOYEE_ID into g
select new
{
EmployeeId = g.Key,
SpecialtyCode = string.Join(",", g.Select(x =>
x.SPECIALTY_CODE))
};
var query2 = (from a in query
join b in context.EMPLOYEEs on a.EmployeeId equals b.EMPLOYEE_ID
select new EmployeeSpecialtyArea
{
EmployeeId = b.EMPLOYEE_ID,
LastName = b.LAST_NAME,
SpecialtyCode = a.SpecialtyCode
});
ViewBag.EmployeeSpecialtyArea = query2;
I hope this may help someone!

How to sort an IEnumerable object by a nested IEnumerable object? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Sort a field of each object in a list with LINQ
I have this collection:
IEnumerable<sample> sam = new List<sample>()
{
new sample{ id = 1, name = "sample 1", list = new List<int>{5,6,1}},
new sample{ id = 2, name = "sample 1", list = new List<int>{2,9}},
new sample{ id = 3, name = "sample 1", list = new List<int>{8,3,7}},
new sample{ id = 4, name = "sample 1", list = new List<int>{8,4,3}},
new sample{ id = 5, name = "sample 1", list = new List<int>{5,1,7}},
new sample{ id = 6, name = "sample 1", list = new List<int>{6,9,7}}
};
How can I sort this using LINQ so that the output is:
new sample{ id = 2, name = "sample 1", list = new List<int>{2,9}},
new sample{ id = 5, name = "sample 1", list = new List<int>{5,1,7}},
new sample{ id = 1, name = "sample 1", list = new List<int>{5,6,1}},
new sample{ id = 6, name = "sample 1", list = new List<int>{6,9,7}}
new sample{ id = 3, name = "sample 1", list = new List<int>{8,3,7}},
new sample{ id = 4, name = "sample 1", list = new List<int>{8,4,3}},
This is sort by 'list' by the way.
Thanks
Here's the LINQ to order sam by the first item of the list property (I gather that's what you're after, right?):
IEnumerable<sample> orderedSam = sam.OrderBy(item => item.list.FirstOrDefault());

Categories