简体   繁体   中英

C# Comparison operators not supported for type Dictionary<string,string>

I get a dictionary and i want to get the matching database entries for the key field in the dictionary. So the code below gets all database fields that equals the data in the dictionary.keys. So far so good. Now when i loop it and i try to get the field from the fields that matches the key x it fails with an exception:

{"Comparison operators not supported for type 'System.Collections.Generic.Dictionary`2+KeyCollection[System.String,System.String]'"}

var fields = _dc.fieldInfos.Where(x => x.name.Equals(param.MethodData.Keys));
foreach (var entry in param.MethodData)
{
    KeyValuePair<string, string> entry1 = entry;
    var field = fields.SingleOrDefault(x => x.name.Equals(entry1.Key));
    if (field == null)
    ....
}

The line that fails is this:

var field = fields.SingleOrDefault(x => x.name.Equals(entry1.Key));

Any ideas?

This is because the LINQ to SQL provider cannot translate the C# expression passed to the SingleOrDefault method into an SQL statement.

You can easily solve this problem by having LINQ to SQL execute the fields query before filtering it further with the SingleOrDefault method. This way the second operation will happen on the collection of objects in memory instead of the database:

var field = fields.ToList().SingleOrDefault(x => x.name.Equals(entry1.Key));

Related resources:

Be mindful that the _dc.fieldInfos.Where(x => x.name.Equals(param.MethodData.Keys)) (line 1) doesn't actually get executed until you try to iterate over fields (line 5).

At that point, x.name.Equals(param.MethodData.Keys) fails because a string (x.name) cannot be compared to KeyCollection<string> (param.MethodData.Keys).

Essentially, you are getting the exception on unexpected line because of the deferred execution.

Are you sure it's not this line that's failing:

var fields = _dc.fieldInfos.Where(x => x.name.Equals(param.MethodData.Keys)); 

as name isn't going to match a collection of strings.

which if so, I'd rewrite as:

var fields = _dc.fieldInfos.Where(x => param.MethodData.Keys.Contains(x.name));

entry1.key is a string, so I can't see why the line that you highlighted would fail with that message.

var fields = _dc.fieldInfos.Where(x => x.name.Equals(param.MethodData.Keys));

This retrieves (actually filters with deferred execution) fieldInfos by matching their name to a collection of keys. I don't know what fieldInfo.Name and param.MethodData.Keys mean, but i assume it's not what you want.

I'd suggest something along the lines of:

var pairs = param.MethodData.Join(_dc.fieldInfos, 
    kvp => kvp.Key, 
    fi => fi.name, 
    (kvp, fi) => new { Key = kvp.Key, FieldInfo = fi });

foreach (var pair in pairs)
    param.MethodData[pair.Key] = pair.FieldInfo;

Im not exactly sure it's gonna work in Linq to SQL though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM