Saturday, May 30, 2009

MS Solver Foundation Data Binding problem

This program gives an exception I don't understand:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Data;
using System.Data.OleDb;
using System.Data.Linq;
using System.Text;
using Microsoft.SolverFoundation.Services;
using System.IO;

    class Test 
        /// <summary> 
        /// Called by the OS 
        /// </summary> 
        /// <param name="args"></param> 
        static void Main(string[] args) 
            Test t = new Test(); 

        /// <summary> 
        /// Holds the OML model 
        /// </summary> 
        string strModel = @"Model[ 


                 Foreach[{i,I}, x[i]==p[i]] 

        /// <summary> 
        ///  SFS 
        /// </summary> 
        SolverContext context; 

        /// <summary> 
        ///  Constructor 
        /// </summary> 
        public Test() 
            context = SolverContext.GetContext(); 

        /// <summary> 
        /// Solve the problem 
        /// </summary> 
        public void Solve() 
            context.LoadModel(FileFormat.OML, new StringReader(strModel)); 

            DataTable dt = new DataTable(); 
            dt.Columns.Add("index", System.Type.GetType("System.String")); 
            dt.Columns.Add("value", System.Type.GetType("System.Double")); 
            dt.Rows.Add("a", 1); 
            dt.Rows.Add("b", 2); 

           DataTable dt2 = new DataTable(); 
            dt2.Columns.Add("index", System.Type.GetType("System.String")); 
            dt2.Columns.Add("value", System.Type.GetType("System.Double")); 
            dt2.Rows.Add("a", -1); 
            dt2.Rows.Add("b", -1); 
           Parameter p = context.CurrentModel.Parameters.First(q => q.Name == "p"); 
            p.SetBinding(dt.AsEnumerable(), "value", new string[] { "index" }); 

            Decision x = context.CurrentModel.Decisions.First(d => d.Name == "x"); 

            // next statement gives: 
            // The property or field 'value' was not found 
>>>>>>>     x.SetBinding(dt2.AsEnumerable(), "value", new string[] { "index" }); <<<<<<<<<<<<

            Solution solution = context.Solve(); 
           Console.Write("{0}", solution.GetReport()); 


The exception is


The data binding on the parameter p works fine. But the same data binding on the variable x fails. I am afraid I don’t understand this. The error message is not helping me: there is actually a column ‘value’.

I have fired off a question to this effect in the forum at

Note that I easily can bind the decision to a List, and then move the data in the List to the DataTable myself.


  1. You will want to replace your binding to x with the following code:
    x.SetBinding(dt2.AsEnumerable().Select(dr => new { value = dr["value"], index = dr["index"] }), "value", "index");

    In fact binding on decisions requires that the name that you specify as value (or index) property exists in the object as either a field or a property, and not as an index of some collection.
    After fixing that your code still hangs on
    because I've used an anonymous type, which apparently doesn't include property setters, but implementing a concrete type (a struct?) should be enough to get your code to run as expected.

  2. Thanks. Yes, I understand that. However look at the parameter binding. I believe that if using an index is allowed in parameter binding it should also be allowed in decision binding.

  3. That's a problem of API consistency. While I totally agree with you, the problem is at design level and not code-wise :)