简体   繁体   中英

Populating KeyValuePair from stored procedure with IMultipleResults fails due to parameterless constructor

I'm trying to find a good way to get all my lookups that populate drop down lists in one DB trip and using generics so I don't have to create a bunch of custom classes. I'd like to avoid creating a bunch of custom classes, like Class IntStringPair , Class StringStringPair , Class StringIntPair , etc.

I know C# has KeyValuePair so I tried using that, but it throws the exception: 'System.Collections.Generic.KeyValuePair[System.Int32,System.String]' must declare a default (parameterless) constructor in order to be constructed during mapping.'

I saw this post: KeyValuePair - no parameterless constructor?

but what's odd is it works if I only hit one table, but fails if I use IMultipleResults from a stored procedure.

So this works:

using (MyDataContext db = new MyDataContext(Config.CoreDBConnectionString))
{
    return db.MyTable.Select(p => new KeyValuePair<string, string>(p.Field1, p.Field2)).ToList();
}

But this fails:

using (MyDataContext db = new MyDataContext(Config.CoreDBConnectionString))
{
    System.Data.Linq.IMultipleResults r = db.GetLookups();
    return r.GetResult<KeyValuePair<int,string>>().ToList();
}

If I could get this last one to work then I'd have the best of both worlds, a single DB trip and a genericized solution.

I've also tried Dictionary but I always run into serialization problems. The application I'm working on is old so instead of Entity Framework it uses Linq to SQL.

So is there a way to do this without creating a bunch of classes, preferably something built into C#/.NET that uses generics and allows me to get multiple result sets in one trip?

If you create your own generic pair class, you can use that. I created one with Value1 and Value2 properties, but you could create Key / Value instead if preferred:

public class DBPair<T1, T2> {
    T1 v1;
    T2 v2;

    public DBPair() {
    }

    public DBPair(T1 v1, T2 v2) {
        this.v1 = v1;
        this.v2 = v2;
    }

    public T1 Value1
    {
        get; set;
    }
    public T2 Value2
    {
        get; set;
    }
}

NOTE: If you need some of the other capabilities of KeyValuePair , like memberwise equality testing or hashcode generation, you will need to add those methods, or transfer the results into a new KeyValuePair after retrieval.

Then you can use it like so:

using (MyDataContext db = new MyDataContext(Config.CoreDBConnectionString))        
    return db.GetLookups().GetResult<DBPair<int,string>>().ToList();

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