ExecuteQuery and properties

Discussion of open issues, suggestions and bugs regarding LinqConnect – Devart's LINQ to SQL compatible ORM
Post Reply
ralfe
Posts: 1
Joined: Sat 13 Jun 2009 13:52

ExecuteQuery and properties

Post by 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.

AndreyR
Devart Team
Posts: 2919
Joined: Mon 07 Jul 2008 13:16

Post by 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.

genesplitter
Posts: 7
Joined: Sat 08 Aug 2009 00:08

Post by 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?

StanislavK
Devart Team
Posts: 1710
Joined: Thu 03 Dec 2009 10:48

Post by 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.

genesplitter
Posts: 7
Joined: Sat 08 Aug 2009 00:08

Post by genesplitter » Wed 06 Apr 2011 20:43

Your suggestion worked perfectly. Thank you.

Post Reply