Page 1 of 1

ExecuteQuery and properties

Posted: Sat 13 Jun 2009 14:00
by ralfe
When using the ExecuteQuery() method on the DataContext the mapping to the defined type is only possible with public fields but not with properties!

This works:

Code: Select all

Class MyProduct
        Public ID As Integer
        Public Name As String
        Public Preis As Decimal
End Class

Sub Main()
        Dim sql2 As String = "SELECT id, name, preis FROM produkt"

        Using ctx As New db.TestDB()
            Dim produkte = ctx.ExecuteQuery(Of MyProduct)(sql2, New Object() {})

            For Each p In produkte
                Console.WriteLine("ID: {0}, Name: {1}, Preis: {2:C}", p.ID, p.Name, p.Preis)
            Next
        End Using

        Console.ReadLine()
End Sub
Then you use properties instead of fields you get a exception saying that the field idValue isn't found in the resultset.

And please document the ExecuteQuerya dn ExecuteCommand methods and their limitations.

Posted: Tue 16 Jun 2009 09:51
by AndreyR
You can read about the ExecuteQuery method here:
http://msdn.microsoft.com/en-us/library/bb534292.aspx
Our implementation follows the Microsoft one, so there should be a mapping between field and property.

Posted: Tue 05 Apr 2011 20:22
by genesplitter
I have the identical behaviour with ExecuteQuery when defining my object fields as properties. Defining the fields as public variables work fine.

var query = ctx.ExecuteQuery("select STATUS from proposal");
foreach (var row in query)
{
string dummy = row.STATUS;
}

public class Thing
{
public string STATUS { get; set; } //does not work, but changing to a public variable works.
}

This throws the following error:


System.InvalidOperationException was unhandled by user code
Message=Field with name k__BackingField is not found in resultset.
Source=Devart.Data.Linq
StackTrace:
at Devart.Data.Linq.Provider.g.a(IDataRecord A_0, String A_1, DataSourceInfo A_2)
at lambda_method(ExecutionScope , b )
at Devart.Data.Linq.Provider.ObjectReader`1.g()
at Devart.Data.Linq.Provider.ObjectReader`1.b()
at Devart.Data.Linq.Provider.ObjectReader`1.MoveNext()


If I change ctx.ExecuteQuery to ctx.ExecuteQuery then it works fine, or changing the properties to public variables work too (public string STATUS). What was the solution to the original problem?

Posted: Wed 06 Apr 2011 17:10
by StanislavK
The problem is that all Thing fields should be filled from the ExecuteQuery result set. By default, a column is mapped to the field with the same name (in your example, such field would be 'STATUS'). Since the field name is auto-generated, it may differ; in this case, it won't be filled and an exception will be thrown. Thus, you can specify the field name directly:

Code: Select all

public class Thing {

  private string status; 
  public string STATUS {

    get { return status; } 
    set { status = value; }
  }
}
Otherwise, you can provide the mapping attributes specifying the columns which properties should be mapped to:

Code: Select all

[Table (Name = "proposal")]
public class Thing { 

  [Column (Name = "STATUS")]
  public string STATUS { get; set; }
}
Please tell us if this helps.

Posted: Wed 06 Apr 2011 20:43
by genesplitter
Your suggestion worked perfectly. Thank you.