1

I want to add result of 3 linq to a single dict.

Dictionary<string, string> dict = new Dictionary<string, string>();        
dict = ctx.tbl1.Where(a => a.Id == cid).ToDictionary(a => a.FieldName, a => a.LabelName);                   
dict = ctx.tbl2.Where(a => a.Id == cid).ToDictionary(a => a.FieldName, a => a.LabelName);   
dict = ctx.tbl3.Where(a => a.Id == cid).ToDictionary(a => a.FieldName, a => a.LabelName);                    
return dict;

The above code gives the last dict results. How to add to dictionary with every linq query result?

Anup
  • 9,396
  • 16
  • 74
  • 138

3 Answers3

2

Try this:

Dictionary<string, string> dict = new Dictionary<string, string>();        
foreach (var a in ctx.tbl1.Where(a => a.Id == cid)) dict.Add(a.FieldName, a.LabelName);
foreach (var a in ctx.tbl2.Where(a => a.Id == cid)) dict.Add(a.FieldName, a.LabelName);
foreach (var a in ctx.tbl3.Where(a => a.Id == cid)) dict.Add(a.FieldName, a.LabelName);
return dict;

A few things to consider, though:

This will throw if the same (case-sensitive) a.FieldName appears in more than one table or more than once in the same table for a given a.Id.

Does the underlying DB have constraints to prevent this from happening? If probably ought to, unless the nature of the data is such that one a.FieldName could legitimately appear more than once for a given a.Id. In that latter case, mapping them into a ILookup may be more appropriate.

If a.FieldName is not case-sensitive, create the dictionary with a case-insensitive string comparer.

If uniqueness of a.Id,a.FieldName applies across the aggregate of the 3 tables, would it make more sense for them to be replaced with a single table?

Jon
  • 126
  • 1
  • 4
0

You can first create your IEnumerable and then at the end convert it to Dictionary.

Provided your model is as below,

public class DummyModel
{
    private const decimal MinValue = 0m;
    public int Id { get; set; }
    public string FieldName { get; set; }
    public string LabelName { get; set; }

    //[DecimalValidatorAttrubute(precision: 2, maxdigits: 2, minValue: decimal.MinValue, maxValue: 99.99m)]
    //public decimal Decimal { get; set; }
}

Method below

private Dictionary<string, string> getDictionary()
    {
        var tbl1 = new List<DummyModel>() { new DummyModel() { Id = 1, FieldName = "Field1", LabelName = "Label1" }, new DummyModel() { FieldName = "Field2", LabelName = "Label2" } };
        var tbl2 = new List<DummyModel>() { new DummyModel() { Id = 1, FieldName = "Field3", LabelName = "Label3" }, new DummyModel() { FieldName = "Field4", LabelName = "Label4" } };
        var tbl3 = new List<DummyModel>() { new DummyModel() {Id = 1,FieldName = "Field5", LabelName = "Label5" }, new DummyModel() { FieldName = "Field6", LabelName = "Label6" } };
        const int cid = 1;

        Dictionary<string, string> dict = new Dictionary<string, string>();
        dict = tbl1.Where(a => a.Id == cid)
            .Concat(tbl2.Where(a => a.Id == cid))
            .Concat(tbl3.Where(a => a.Id == cid))
            .ToDictionary(a => a.FieldName, a => a.LabelName);
        return dict;
    }

Would help you to achive something like

[TestMethod]
    public void LinqDictionary()
    {
        var dict = getDictionary();
        foreach (var item in dict)
        {
            Console.WriteLine("FieldName {0}, LabelName {1} ", item.Key, item.Value);
        }

    }

Output

FieldName Field1, LabelName Label1
FieldName Field3, LabelName Label3 
FieldName Field5, LabelName Label5
Rajnikant
  • 2,176
  • 24
  • 23
0

To add items to a dictionary from multiple queries,I use a bit more linq, directly add the first set to the dictionary, then use tolist and foreach to add subsequent items. I doubt performance is super, but in this case (adding controls) ts not likely to matter and TBH I doubt ToDictionary performs significantly faster anyway.

Dictionary<string, SomeObject> controlsChanged;
controlsChanged = this.Controls.OfType<TextBox>().Select(c => c.Name).ToDictionary(k => k, v => new SomeObject());
this.Controls.OfType<ComboBox>().ToList().ForEach(c => controlsChanged.Add(c.Name, new SomeObject()));
gbjbaanb
  • 51,617
  • 12
  • 104
  • 148