public class MyFiles
{
public int Id { get; set; }
public string FileName { get; set; }
public IDictionary<string, string> Metadata { get; set; } = new Dictionary<string, string>();
}
private void button1_Click(object sender, EventArgs e)
{
var list = new List<MyFiles>();
list.Add(new MyFiles
{
Id = 1,
FileName = "myTestfile.jpg",
Metadata = new Dictionary<string, string>
{
{ "FileSize", "599" },
{ "GroupId", "25" },
{ "TypeId", "Finance" },
}
});
list.Add(new MyFiles
{
Id = 2,
FileName = "myTestfile1.jpg",
Metadata = new Dictionary<string, string>
{
{ "FileSize", "748" },
{ "GroupId", "25" },
{ "TypeId", "HR" },
}
});
list.Add(new MyFiles
{
Id = 3,
FileName = "myTestfile23.jpg",
Metadata = new Dictionary<string, string>
{
{ "FileSize", "718" },
{ "GroupId", "78" },
{ "TypeId", "IT" },
}
});
list.Add(new MyFiles
{
Id = 4,
FileName = "myTestfile2.jpg",
Metadata = new Dictionary<string, string>
{
{ "FileSize", "783" },
{ "GroupId", "78" },
{ "TypeId", "IT" },
}
});
// Instance one
var queryDictionary = new Dictionary<string, string>();
queryDictionary.Add("GroupId", "78");
queryDictionary.Add("TypeId", "IT");
// Expected results would be Ids: 3 and 4
// Instance two
queryDictionary.Clear();
queryDictionary.Add("GroupId", "78");
queryDictionary.Add("FileSize", "783");
// Expected results would be Ids: 4
}
public IEnumerable<AzureStorageFileDownloadResultDTO> GetFiles(IDictionary<string, string> metadata, BlobContainerClientDTO blobContainerClient)
{
}
Directly above is what I would like it to be, but I can't figure out how to query it properly.
Here I'm only checking one key value pair where I need to check a dictionary of metadata <string, string>():
public IEnumerable<AzureStorageFileDownloadResultDTO> GetFiles(ModuleType moduleType, string metadataKey, string metadataValue, BlobContainerClientDTO blobContainerClient)
{
if (blobContainerClient == null)
{
throw new ArgumentNullException(nameof(blobContainerClient));
}
if (string.IsNullOrWhiteSpace(blobContainerClient.ConnectionString) == true)
{
throw new PropertyNullOrWhiteSpaceException(nameof(blobContainerClient.ConnectionString));
}
if (string.IsNullOrWhiteSpace(blobContainerClient.ContainerName) == true)
{
throw new PropertyNullOrWhiteSpaceException(nameof(blobContainerClient.ContainerName));
}
if (moduleType == ModuleType.None)
{
throw new ArgumentNullException(nameof(moduleType));
}
if (string.IsNullOrWhiteSpace(metadataKey) == true)
{
throw new ArgumentOutOfRangeException(nameof(metadataKey));
}
if (string.IsNullOrWhiteSpace(metadataKey) == true)
{
throw new PropertyNullOrWhiteSpaceException(nameof(metadataKey));
}
if (string.IsNullOrWhiteSpace(metadataValue) == true)
{
throw new PropertyNullOrWhiteSpaceException(nameof(metadataValue));
}
BlobContainerClient container = GetBlobContainerForDownloads(blobContainerClient);
var blobItems = GetAllBlobsForContainer(container);
if (blobItems == null)
{
return Enumerable.Empty<AzureStorageFileDownloadResultDTO>();
}
IList<AzureStorageFileDownloadResultDTO> results = new List<AzureStorageFileDownloadResultDTO>();
AzureStorageFileDownloadResultDTO result;
// pull all blob items within the container where there is a meta data match for the file manager module type AND the meta data key and value passed in AND there is not a value of IsFileDeleted as "true"
foreach (var item in blobItems.Where(w => w.Metadata.Contains(new KeyValuePair<string, string>(FileManagerMetadataContants.ModuleType, moduleType.ToString())) == true && w.Metadata.Contains(new KeyValuePair<string, string>(metadataKey, metadataValue)) == true && w.Metadata.Contains(new KeyValuePair<string, string>(FileManagerMetadataContants.IsFileDeleted, FileManagerMetadataContants.IsFileDeletedValue)) == false))
{
result = new AzureStorageFileDownloadResultDTO()
{
FileData = null, // do not pull the file data when returning all the files ; the developer will return back to the API to get the actual file with the blob name
FileFound = true,
BlobName = item.Name,
FileName = GetFileName(item.Metadata),
FileNameWithExtension = GetFileNameWithExtension(item.Metadata),
ContentType = item.Properties.ContentType,
FileExtension = item.Properties.ContentType,
Metadata = item.Metadata
};
results.Add(result);
}
return results;
}
I've tried this, but it isn't working. It will remove the blob item with a meta data custom item as IsFileDeleted as true and IsFileDeletedValue was true, but does not removed the blobItem with a ModuleId as 3, as I am passing in for the ModuleId item to
be 5.
foreach (var item in blobItems.Where(w => w.Metadata.Any(a => (metadata.Select(s => s.Key).Contains(a.Key) == true
&& metadata.Select(s => s.Value).Contains(a.Value) == true)
&& (metadata.Select(s => s.Key).Contains(FileManagerMetadataContants.IsFileDeleted) == false
&& metadata.Select(s => s.Key).Contains(FileManagerMetadataContants.IsFileDeletedValue) == false)) == true))
{
var newFileItem = new FileItemDTO
{
Id = item.Name,
FileId = GetMetadataValue(item.Metadata, FileManagerMetadataContants.FileId),
FileName = GetMetadataValue(item.Metadata, FileManagerMetadataContants.FileName),
FileNameWithExtension = GetMetadataValue(item.Metadata, FileManagerMetadataContants.FileNameWithExtension),
FileExtension = GetMetadataValue(item.Metadata, FileManagerMetadataContants.FileExtension),
FileSize = item.Properties.ContentLength ?? 0,
ModuleId = GetMetadataValue(item.Metadata, FileManagerMetadataContants.ModuleId),
EndItemId = GetMetadataValue(item.Metadata, FileManagerMetadataContants.EndItemId),
EndItemTypeId = GetMetadataValue(item.Metadata, FileManagerMetadataContants.EndItemTypeId),
MetadataDictionary = item.Metadata,
};
// Convert the metadata dictionary into a IList<MetadataDTO> so that the developer can query against it easier compared to querying against a dictionary
foreach (var itemMetadataJson in newFileItem.MetadataDictionary)
{
newFileItem.Metadata.Add(new MetadataDTO { Key = itemMetadataJson.Key, Value = itemMetadataJson.Value });
}
fileItems.Add(newFileItem);
}
Calling MatchOnQuery(queryDictionary, list) returns you the matching MyFiles
(BTW - personal bugbear of mine, MtFiles seems to model a single thing - a file. Give it a singular name - MyFile. It really makes a big difference when you are thinking about the logic and playing with possible code to have singular names for single things
and plural names for plural things.)
(BTW-2 - Thanks for the succinct sample, data and expectations. It would be great if more questions were presented like you have done. Having a sample which can be executed with known results makes it so much easier for people to help)
Calling MatchOnQuery(queryDictionary, list) returns you the matching MyFiles
(BTW - personal bugbear of mine, MtFiles seems to model a single thing - a file. Give it a singular name - MyFile. It really makes a big difference when you are thinking about the logic and playing with possible code to have singular names for single things
and plural names for plural things.)
(BTW-2 - Thanks for the succinct sample, data and expectations. It would be great if more questions were presented like you have done. Having a sample which can be executed with known results makes it so much easier for people to help)
Thanks PaulTheSmith!
This is close to what I ended up doing.
Here is mine:
// only pull blobItems with metadata that match AND that are not deleted.
blobItems = blobItems.Where(
mf => metadata.All(
kvp => mf.Metadata.TryGetValue(kvp.Key, out var outMetadata) && outMetadata == kvp.Value
&& (mf.Metadata.TryGetValue(FileManagerMetadataContants.IsFileDeleted, out var outIsFileDelete) && outIsFileDelete == FileManagerMetadataContants.IsFileDeletedValue) == false));
Participant
1038 Points
2816 Posts
How to query a dictionary by another dictionary in C#
Jan 18, 2021 03:28 PM|tvb2727|LINK
Hello,
I need to query a dictionary by another dictionary
var dictionary = new Dictionary<string, string>();
var queryDictionary = new Dictionary<string, string>();
So I want to query dictionary and only pull back what matches in queryDictionary based on the <key, value>().
I can't seem to figure it out.
I've tried KeyValue pairs, but it doesn't work.
All-Star
53001 Points
23593 Posts
Re: How to query a dictionary by another dictionary in C#
Jan 18, 2021 03:35 PM|mgebhard|LINK
Shared sample data, code, and expected results.
Participant
1038 Points
2816 Posts
Re: How to query a dictionary by another dictionary in C#
Jan 18, 2021 03:57 PM|tvb2727|LINK
Data, Code, expected results:
Directly above is what I would like it to be, but I can't figure out how to query it properly.
Participant
1038 Points
2816 Posts
Re: How to query a dictionary by another dictionary in C#
Jan 18, 2021 04:07 PM|tvb2727|LINK
Here is the initial code.
Here I'm only checking one key value pair where I need to check a dictionary of metadata <string, string>():
Participant
1038 Points
2816 Posts
Re: How to query a dictionary by another dictionary in C#
Jan 18, 2021 04:23 PM|tvb2727|LINK
Here is what the error looks like when I try to just do .Contains() on the metadata:
Error CS1503 Argument 1: cannot convert from 'System.Collections.Generic.IDictionary<string, string>' to 'System.Collections.Generic.KeyValuePair<string, string>'
https://imgur.com/a/BMdRXLf
Participant
1038 Points
2816 Posts
Re: How to query a dictionary by another dictionary in C#
Jan 18, 2021 08:51 PM|tvb2727|LINK
I've tried this, but it isn't working. It will remove the blob item with a meta data custom item as IsFileDeleted as true and IsFileDeletedValue was true, but does not removed the blobItem with a ModuleId as 3, as I am passing in for the ModuleId item to be 5.
All-Star
160042 Points
13198 Posts
ASPInsiders
Moderator
Re: How to query a dictionary by another dictionary in C#
Jan 18, 2021 08:53 PM|mbanavige|LINK
I think i would approach this by looking for the Intersect of the 2 disctionaries.
https://stackoverflow.com/questions/10685142/c-sharp-dictionaries-intersect
Participant
1038 Points
2816 Posts
Re: How to query a dictionary by another dictionary in C#
Jan 18, 2021 09:22 PM|tvb2727|LINK
This is just checking the key though. I need to check the Key and the Value to make sure they match?
Participant
1038 Points
2816 Posts
Re: How to query a dictionary by another dictionary in C#
Jan 18, 2021 09:29 PM|tvb2727|LINK
Mine are set as IDictionary, I think they need to be Dictionary before the .ContainsValue is available.
Participant
1620 Points
927 Posts
Re: How to query a dictionary by another dictionary in C#
Jan 18, 2021 10:39 PM|PaulTheSmith|LINK
I would create a little method since the logic is complex
Calling MatchOnQuery(queryDictionary, list) returns you the matching MyFiles
(BTW - personal bugbear of mine, MtFiles seems to model a single thing - a file. Give it a singular name - MyFile. It really makes a big difference when you are thinking about the logic and playing with possible code to have singular names for single things and plural names for plural things.)
(BTW-2 - Thanks for the succinct sample, data and expectations. It would be great if more questions were presented like you have done. Having a sample which can be executed with known results makes it so much easier for people to help)
Participant
1038 Points
2816 Posts
Re: How to query a dictionary by another dictionary in C#
Jan 19, 2021 02:41 PM|tvb2727|LINK
Thanks PaulTheSmith!
This is close to what I ended up doing.
Here is mine:
Other *possible items: c# - How to query a nested object dictionary against another dictionary key/values matching - Stack Overflow