LINQ - Deserialize JSON column and filter

淺唱寂寞╮ 提交于 2019-12-25 06:27:26

问题


How to deserialize/serialize a property with JSON string array value and then filter (using where clause) in LINQ inside a lambda expression?

void Main()
{
    var regionList = new List<Row>() {
        new Row { RegionJsonList = "[\"QLD\",\"NSW\"]" },
        new Row { RegionJsonList = "[\"TAZ\",\"SA\"]" },
        new Row { RegionJsonList = "[\"QLD\",\"VIC\"]" }
    };

    var filterRegionList = new List<string>() {
        "QLD", "NSW"
    };

    var queryable = regionList.AsQueryable();


    // this is obviously wrong, i just want to find the Row that contains one on filterRegionList
    var result = queryable.Where(r => JsonConvert.DeserializeObject<string[]>(r.RegionJsonList).Contains(filterRegionList));

    result.Count().Dump(); // should be 2

}

class Row
{
    public string RegionJsonList { get;set; }
}

回答1:


Following would work:

var result =
filterRegionList.Aggregate(regionList,(current,filter) => 
current.Where( r => r.RegionJsonList.Contains(filter)).ToList())

Aggregating the filterRegionList and regionList and thus applying filters for the final result. I did not find a requirement to Deserialize the RegionJsonList, since this would work as is, but you may add that part in case you are keen.

Also we are applying And filter via aggregation, it checks for the rows which contains both the filters, and thus provide the result, you may modify filter to achieve more number of rows, like following will select two entries from original regionList

var filterRegionList = new List<string>() { "QLD"  };



回答2:


To filter for rows that contain at least one of the entries from filterRegionList, you can use Enumerable.Intersect and check for non-empty intersections:

var resultAny = queryable.Where(r => JsonConvert.DeserializeObject<string[]>(r.RegionJsonList).Intersect(filterRegionList).Any());

To filter for rows that contain all of the entries from filterRegionList, you can use Enumerable.Except to remove the row's entries from the filter list. If everything gets removed, it's a match:

var resultAll = queryable.Where(r => !filterRegionList.Except(JsonConvert.DeserializeObject<string[]>(r.RegionJsonList)).Any());

(It wasn't entirely clear from your question which you wanted.)



来源:https://stackoverflow.com/questions/36393082/linq-deserialize-json-column-and-filter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!