Using LINQ Where with ArrayList item - c#

Someone can help me? How can I get all appsRelatedIds IN arrayList? I work on Api integration and I have the class Apps:
public class Apps
{
[JsonProperty("id")]
public string Id { get; set; }
[JsonProperty("active")]
public bool Active { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
[JsonProperty("appsRelatedIds")]
public ArrayList RelatedId { get; set; }
}
I've created this LINQ and works fine:
var appsFiltered = AppsList.Where(x => x.Active == true && x.Description.Contains("Top")).ToList();
But I need to get by RelatedIds like and for this response the API returns only ids related:
int relatedId = 5;
var appsFiltered = AppsList.Where(x => x.Active == true && x.RelatedId.Contains(relatedId).ToList();
Example Data:
line1 - Id 1234 Active=true Description='Top Gun' RelatedId= [ 1, 2, 3, 4, 5 ]
line2 - Id 12345 Active=true Description='Top Gun' Maverick' RelatedId= [ 1, 3, 4, 5 ]
line3 - Id 123456 Active=true
Description='Transformers' RelatedId=[ 7,8,9]
In this case I need appsFiltered with line1 and line2 because relatedId parameter 5 is inside RelatedId ArrayList.
I tried to use a LINQ

Why using ArrayList instead of List?
ArrayList are usually slow in performance
var appsFiltered = AppsList.Where(x => x.Active == true && x.RelatedId.Any(a=> a == relatedId).ToList();

Related

Push records from one model array to another model array with conditions

I have below two models:
TrackList:
public int id { get; set; }
public string name { get; set; }
public int apr_by { get; set; }
public int reg_by { get; set; }
TrackListMain:
public int id { get; set; }
public string name { get; set; }
public string status { get; set; }
Suppose I would get the below records from DB in the model array TrackList by executing:
var dbArray = await _SQLHelper.GetRecords<TrackList>("[TASKLIST]", parameters);
id
name
apr_by
reg_by
1
aaa
1
1
2
bbb
2
null
3
ccc
null
3
4
ddd
null
null
Now I need to push each record to the model array TrackListMain based on these conditions:
foreach dbArray => {
if (`dbArray.apr_by` == null && `reg_by` == null), push to `TrackListMain` and update `status` field with `null`
if `dbArray.apr_by` !=null, push to `TrackListMain` and update `status` field with `AB`
if `dbArray.reg_by` !=null, push to `TrackListMain` and update `status` field with `RB`
}
And my resultant array IEnumerable<TrackListMain> mainArray should contain data with the below format:
id
name
status
1
aaa
AB
1
aaa
RB
2
bbb
AB
3
ccc
RB
4
ddd
null
Can you help me to achieve this in C# either by using LINQ?
For LINQ approach,
Filter data by conditions (3 sets) and decorate the output result.
Combine 3 set of data into one with .Union().
Order the result by Id.
List<TrackListMain> result = (dbArray.Where(x => x.Apr_By == null && x.Reg_By == null)
.Select(x => new TrackListMain
{
Id = x.Id,
Name = x.Name,
Status = null
})
)
.Union(dbArray.Where(x => x.Apr_By != null)
.Select(x => new TrackListMain
{
Id = x.Id,
Name = x.Name,
Status = "AB"
})
)
.Union(dbArray.Where(x => x.Reg_By != null)
.Select(x => new TrackListMain
{
Id = x.Id,
Name = x.Name,
Status = "RB"
})
)
.OrderBy(x => x.Id)
.ToList();
Demo # .NET Fiddle
First of all you should make sure how the _SQLHelper behaves if the values in database are null.
If it returns null then you need to make the class properties nullable:
TrackList
public int id { get; set; }
public string name { get; set; }
public int? apr_by { get; set; }
public int? reg_by { get; set; }
Otherwise it makes no sense to check them for null in C# (then you would probably check if they are 0 which is int default value).
The query could look like this:
You need this using:
using System.Linq;
var mainArray = dbArray.Select(x => new TrackListMain
{
id = x.id,
name = x.name,
status = x.apr_by == null ? (x.reg_by == null ? null : "RB") : "AB"
});
It is not very readable tho, so maybe better go with a method:
var mainArray = dbArray.Select(ConvertTrackList);
private static TrackListMain ConvertTrackList(TrackList trackList)
{
var main = new TrackListMain()
{
id = trackList.id,
name = trackList.name
};
if (trackList.apr_by != null)
main.status = "AB";
else if (trackList.reg_by != null)
main.status = "RB";
return main;
}

How to get records if only all of the list elements included in nested collections?

I want to filter my query using MongoDb c# driver. I have a query list so I need to filter records if all the list item included in the sub collection of a collection.
public class Hotels
{
[BsonId]
// standard BSonId generated by MongoDb
public ObjectId InternalId { get; set; }
public string Id { get; set; }
public string Name { get; set; }
public List<int> Amenities { get; set; }
}
I have a query parameter "amenities" as string then splitted with respect to ",".
if (!string.IsNullOrEmpty(amenties))
{
var amenityList =Array.ConvertAll<string,int>( amenties.Split(","),int.Parse).ToList();
filter &= Builders<Hotels>.Filter.Where(r => r.Amenities.All(i => amenityList.Contains(i)));
}
var result =_context.GetCollection<Hotels>(typeof(Hotels).Name).Find(filter);
Throws exception : unsupported filter. Thus, how can I fix this query ?
Thanks
your Where expression is wrong. have a look at the last line of the following code for the correct expression.
using MongoDB.Entities;
using System;
using System.Linq;
namespace StackOverflow
{
public class Program
{
public class Hotel : Entity
{
public string Name { get; set; }
public int[] Amenities { get; set; }
}
private static void Main(string[] args)
{
new DB("test");
(new[] {
new Hotel{ Name= "hotel one", Amenities = new[] {1, 3, 5, 7 } },
new Hotel{ Name= "hotel two", Amenities = new[] {2, 4, 6, 8 } }
}).Save();
string amenities = "2,4,6,8";
int[] amenityList = amenities.Split(",").Select(a => Convert.ToInt32(a)).ToArray();
var result = DB.Find<Hotel>()
.Many(h => amenityList.All(a => h.Amenities.Contains(a)));
}
}
}
it generates the following find query:
"command": {
"find": "Hotel",
"filter": {
"Amneties": {
"$all": [
NumberInt("2"),
NumberInt("4"),
NumberInt("6"),
NumberInt("8")
]
}
}
}

Obtaining Child element via LookUp/Something better

I am trying to obtain a child element of a parent element. I have a basic database as so:
public class list
{
public int id { get; set; }
public List<Users> UsersList{ get; set; }
public class Users
{
[Key]
public int Users_id{ get; set; }
public string UserId { get; set; }
}
}
If I was wanting to obtain all of the of the elements in Users that had the specific UserId how would I do that? I am trying to refrain from using a nested for loop and iterating through all my entries of List and Users in the database. I was looking up the LookUp(), but am a bit confused on how to apply it in this case. Any help would be great!
Since you're a bit confused, I'll provide more detail than my original answer. Let's take your code and create a very basic and crude sample program:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace SOSample
{
public class list
{
public int id { get; set; }
public List<Users> UsersList { get; set; }
public class Users
{
[Key]
public int Users_id { get; set; }
public string UserId { get; set; }
}
}
class Program
{
static void Main(string[] args)
{
// Instantiate and initialize with sample data.
var sampleList = new list()
{
id = 12345,
UsersList = new List<list.Users>()
{
new list.Users() { Users_id = 1, UserId = "0042" },
new list.Users() { Users_id = 2, UserId = "0019" },
new list.Users() { Users_id = 3, UserId = "0036" },
new list.Users() { Users_id = 4, UserId = "0214" },
new list.Users() { Users_id = 5, UserId = "0042" },
new list.Users() { Users_id = 6, UserId = "0042" },
new list.Users() { Users_id = 7, UserId = "0019" }
}
};
// Linq search.
var someId = "0042";
var linqQuery = sampleList.UsersList.Where(user => user.UserId == someId);
Console.WriteLine("Linq query results:");
foreach (var r in linqQuery)
{
Console.WriteLine($"Users_id: {r.Users_id}, UserId: {r.UserId}");
}
// Lookup search (using same someId as for Linq).
var lookup = sampleList.UsersList.ToLookup(user => user.UserId);
var lookupQuery = lookup[someId];
Console.WriteLine("\nLookup query results:");
foreach (var r in lookupQuery)
{
Console.WriteLine($"Users_id: {r.Users_id}, UserId: {r.UserId}");
}
}
}
}
Output:
Linq query results:
Users_id: 1, UserId: 0042
Users_id: 5, UserId: 0042
Users_id: 6, UserId: 0042
Lookup query results:
Users_id: 1, UserId: 0042
Users_id: 5, UserId: 0042
Users_id: 6, UserId: 0042
Hope that clarifies things. The major issue I see with your question and comments is that it's possible that you're mistaking nested classes for properties. When you instantiate an outer class, the inner class does not get instantiated and it's not some sort of property of an outer class.
Old answer (provides individual details):
I like using Linq. So, assuming sampleList is of type list:
var query = sampleList.UsersList.Where(user => user.UserId == someId);
That's going to give you IEnumerable<list.Users>. You can always use ToList(), ToArray(), ToDictionary() to get the desired collection type:
var results = sampleList.UsersList.Where(user => user.UserId == someId).ToArray();
As far as Lookup, I've seen a few ways it being used, but the most familiar way for me is this:
var lookup = sampleList.UsersList.ToLookup(user => user.UserId);
var query = lookup[someId];
Once again, that'll give you IEnumerable<list.Users>. Alternatively, you can get the collection type of your choice from that query:
var results = lookup[someId].ToArray();
Basically, you're specifying what the key will represent in that lookup (it's the UserId in this case) and then when the time comes, you search by a key.

Can I have an Any in a linq query?

I'm trying to get an ID from a collection with a bool to tell me if that ID is associated with another value.
So, I have this:
public class RoleAssignment
{
[Key]
public int RoleAssignmentId { get; set; }
public Guid AssigneeId { get; set; }
public int RoleId { get; set; }
}
With this data:
var rAssnd = new List<RoleAssignment>{
{ 2, 0251F0D6-F2C9-E511-8C3C-00215E466552, 48 }
{ 3, 0251F0D6-F2C9-E511-8C3C-00215E466552, 49 }
{ 4, 0251F0D6-F2C9-E511-8C3C-00215E466552, 52 }
{ 5, F48459F5-469F-E511-8172-00215E466552, 44 }
}
So, if I am checking for RoleId 49, I would like to get a result set like this:
0251F0D6-F2C9-E511-8C3C-00215E466552, true
F48459F5-469F-E511-8172-00215E466552, false
Right now I'm trying this:
var results = selected.GroupBy (s => s.AssigneeId, s => s.RoleId == proposalRole);
But this gives me the Guid and a list.
Could I have the second value be something like Any(s.RoleId == proposalRole)?
First group, then use any to check each group for your rule.
var results = rAssnd
.GroupBy(s => s.AssigneeId)
.Select(g => new
{
g.Key,
hasRule = g.Any(s => s.RoleId == proposalRole)
});

ServiceStack OrmLite raising MissingMethodException when selecting objects with references

I'm attempting what I thought was going to be a simple select across two database tables. I'm selecting from an association table called PlayerEquipment that looks like this:
PlayerId | ItemId | Quantity | IsEquipped
----------+--------+----------+------------
1 1 1 1
1 3 1 0
This makes up a player's inventory in our system, mapping to specific IDs in our Player and Item tables.
The associated PlayerEquipment POCO looks like this:
public class PlayerEquipment
{
[Ignore]
public string Id
{
get { return PlayerId + "/" + ItemId; }
}
public int PlayerId { get; set; }
[References(typeof(ItemData))]
public int ItemId { get; set; }
public int Quantity { get; set; }
public bool IsEquipped { get; set; }
[Reference]
public ItemData ItemData { get; set; }
}
For now, ignore the fact that PlayerId isn't associated with a relevant Player object (it will be, eventually).
I'm trying to get a list of equipment for a player, given his ID:
List<PlayerEquipment> equipment = this.Db.LoadSelect<PlayerEquipment>(q => q.PlayerId == playerId);
When I do that call, I get this exception:
Method not found: 'Boolean ServiceStack.EnumerableExtensions.IsEmpty(System.__Canon[])'.
...with this stack trace:
at ServiceStack.OrmLite.OrmLiteReadCommandExtensions.LoadListWithReferences[Into,From](IDbCommand dbCmd, SqlExpression`1 expr, String[] include)
at ServiceStack.OrmLite.ReadExpressionCommandExtensions.LoadSelect[T](IDbCommand dbCmd, Expression`1 predicate, String[] include)
at ServiceStack.OrmLite.OrmLiteReadExpressionsApi.<>c__DisplayClass34`1.<LoadSelect>b__33(IDbCommand dbCmd)
at ServiceStack.OrmLite.OrmLiteExecFilter.Exec[T](IDbConnection dbConn, Func`2 filter)
at ServiceStack.OrmLite.OrmLiteReadExpressionsApi.Exec[T](IDbConnection dbConn, Func`2 filter)
at ServiceStack.OrmLite.OrmLiteReadExpressionsApi.LoadSelect[T](IDbConnection dbConn, Expression`1 predicate, String[] include)
[snip]
Looking online, I haven't found any help for this exception, but I can't imagine how I could make my query any simpler. Am I going about this in the wrong way? Should I instead query a Player or Item object that references a List<PlayerEquipment> property instead?
I've just tried this example in all supported Databases and it's working as expected. The only change was removing [Ignore] which is not allowed on Primary Keys as they need to exist on the underlying RDBMS table.
Types Used
public class PlayerEquipment
{
public string Id
{
get { return PlayerId + "/" + ItemId; }
}
public int PlayerId { get; set; }
[References(typeof(ItemData))]
public int ItemId { get; set; }
public int Quantity { get; set; }
public bool IsEquipped { get; set; }
[Reference]
public ItemData ItemData { get; set; }
}
public class ItemData
{
[AutoIncrement]
public int Id { get; set; }
public string Data { get; set; }
}
Create Tables, Populate Data, Select and Dump Results
db.DropTable<PlayerEquipment>();
db.DropTable<ItemData>();
db.CreateTable<ItemData>();
db.CreateTable<PlayerEquipment>();
var item1 = new ItemData { Data = "ITEM1" };
db.Save(item1);
db.Save(new PlayerEquipment
{
PlayerId = 1,
ItemId = item1.Id,
Quantity = 1,
IsEquipped = true,
});
var item2 = new ItemData { Data = "ITEM2" };
db.Save(item2);
db.Save(new PlayerEquipment
{
PlayerId = 1,
ItemId = item2.Id,
Quantity = 1,
IsEquipped = false,
});
var playerId = 1;
var results = db.LoadSelect<PlayerEquipment>(q => q.PlayerId == playerId);
results.PrintDump();
Console Output
[
{
Id: 1/1,
PlayerId: 1,
ItemId: 1,
Quantity: 1,
IsEquipped: True,
ItemData:
{
Id: 1,
Data: ITEM1
}
},
{
Id: 1/2,
PlayerId: 1,
ItemId: 2,
Quantity: 1,
IsEquipped: False,
ItemData:
{
Id: 2,
Data: ITEM2
}
}
]

Categories

Resources