2

I have settings class

public class Setting 
{
    public virtual string Key { get; set; }
    public virtual string Value { get; set; }
}

and i have to list

IEnumerable<Setting> A1 => contain {"A","1"}{"B","2"}
IEnumerable<Setting> A2 => contain {"A","1"}{"B","5"}

i want linq statment to chose the element from list A2 that have same key and different value here is {"B","5"}

I have try

A2.Where(x => A1.Any(y => y.Value != x.Value)).ToList();

this give me the two elemnts in A2

can any one help me thank you


**Edit ** my settings class

 public class Setting : Entity<int>
{
    public virtual DateTime? ModificationDate { get; set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual string Key { get; set; }
    public virtual string Value { get; set; }
    public virtual string ModifiedBy { get; set; }
    public virtual string Type { get; set; }
    public virtual string ValidateRegex { get; set; }    
    public virtual bool IsSystem { get; set; }

}

and i have return from mvc IEnumerable<Setting> let it name settings,

then i get from database the original settings IEnumerable<Setting> let it name dbsettings

i want to know the changed value from settings to make update on it

1
  • You don't ask for the key. Try A2.Where(x => A1.Any(y => x.Key == y.Key && x.Value != y.Value)) Commented Dec 10, 2015 at 9:23

4 Answers 4

6

You need to compare the Key as well:

A2.Where(x => A1.Any(y => y.Key == x.Key && y.Value != x.Value)).ToList();

The following sample returns { "B", "5" } as the result:

void Main()
{
    var a1 = new List<Setting>(new Setting[] { 
        new Setting() { Key = "A", Value = "1" }, 
        new Setting() { Key = "B", Value = "2" } });
    var a2 = new List<Setting>(new Setting[] { 
        new Setting() { Key = "A", Value = "1" }, 
        new Setting() { Key = "B", Value = "5" } });
    var result = a2.Where(x => a1.Any(y => y.Key == x.Key && y.Value != x.Value)).ToList();
    Console.WriteLine(result);
}

As you are comparing strings, you should be aware that == and != respectively always compares case-sensitive. So the keys need to be written in the same way in both lists (and also differences in case will be recognized as relevant differences). You can also use an overload of string.Compare to specify the comparison options in greater detail.

Sign up to request clarification or add additional context in comments.

3 Comments

@Doha In a sample, the query works with the data provided in the question. Maybe in the real-world-data the keys differ in case. I've updated my answer.
i edit my question to explain my real case , thank you for your help :)
thank you , i have found that value saved in database with spaces , so i must remove it before compare
3

This should do it:

A2.Where(x => A1.Any(y => y.Key == x.Key && y.Value != x.Value))

BTW, your Setting class seems like reinventing the wheel. Dictionary, Tuple and NameValueCollection can all do that for you.

2 Comments

not work it return to me no result , my settings have a lot of values but i put here key and value for simplified
@Doha: Given that you have provided enough information in your question, I do not see any reason for this query not to work.
2
        var A1 = new List<Setting>(){new Setting(){Key = "A", Value = "1"}};
        var A2 = new List<Setting>() { new Setting() { Key = "A", Value = "2" } };
        var a1Keys = A1.Select(x => x.Key).ToList();
        var dupKeys = A2.Where(x => a1Keys.Contains(x.Key)).Select(x=>x.Key);
        var res = A2.Where(x => dupKeys.Contains(x.Key));

Comments

2

For performance reasons you could use a lookup:

var a1KeyLookup = A1.ToLookup(x => x.Key);
List<Setting> a2List = A2
    .Where(a2 => a1KeyLookup[a2.Key].Any(a1 => a1.Value != a2.Value))
    .ToList();

Here's your sample data:

IEnumerable<Setting> A1 = new List<Setting> {
    new Setting{Key="A", Value="1"},
    new Setting{Key="B", Value="2"},
};
IEnumerable<Setting> A2 = new List<Setting> {
    new Setting{Key="A", Value="1"},
    new Setting{Key="B", Value="5"},
};

var a1KeyLookup = A1.ToLookup(x => x.Key);
List<Setting> a2List = A2
    .Where(a2 => a1KeyLookup[a2.Key].Any(a1 => a1.Value != a2.Value))
    .ToList();

It returns as expected a list with a single item: Key="B", Value="5"

2 Comments

@Doha: no, it works as expected. I have tested it with your sample data as shown in my answer.
thank you for your help , i have edit my question for my real case , i don't know if reading from database the use linq make the problem to me

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.