ExecuteQuery and properties

ExecuteQuery and properties

Postby ralfe » Sat 13 Jun 2009 14:00

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.
ralfe
 
Posts: 1
Joined: Sat 13 Jun 2009 13:52

Postby AndreyR » Tue 16 Jun 2009 09:51

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.
AndreyR
Devart Team
 
Posts: 2919
Joined: Mon 07 Jul 2008 13:16

Postby genesplitter » Tue 05 Apr 2011 20:22

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?
genesplitter
 
Posts: 7
Joined: Sat 08 Aug 2009 00:08

Postby StanislavK » Wed 06 Apr 2011 17:10

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.
StanislavK
Devart Team
 
Posts: 1710
Joined: Thu 03 Dec 2009 10:48

Postby genesplitter » Wed 06 Apr 2011 20:43

Your suggestion worked perfectly. Thank you.
genesplitter
 
Posts: 7
Joined: Sat 08 Aug 2009 00:08


Return to LinqConnect (LINQ to SQL support)