简体   繁体   中英

Building SqlExpression throws InvalidOperationException when not using anonymous type in Select() clause

This is my database POCO :

public class MyPoco1
{
    public int Id { get; set; }
    public string Name { get; set; }
}

I want to select and map results into a custom POCO with different property name :

public class MyPocoAlias1
{
    public string OtherName { get; set; }
}

public class MyService : ServiceStack.Service
{
    public List<MyPocoAlias1> Any(MyRequest request)
    {
        // throws InvalidOperationException
        var q1 = Db.From<MyPoco1>().Select(c => new MyPocoAlias1 { OtherName = c.Name });

        // this works
        var q2 = Db.From<MyPoco1>().Select(c => new { OtherName = c.Name });
        var items = Db.Select<MyPocoAlias1>(q2);

        return items;
    }
}

q1 fails with a System.InvalidOperationException :

"variable 'c' of type 'MyPoco1' referenced from scope '', but it is not defined".

q2 works, but is there a way to do this with a strong type (which check correct property names/types) or is this mandatory to use an anonymous type in the .Select() clause ?

The purpose of .Select() in a Typed OrmLite SqlExpression is to specify which fields should be specified in the SELECT expression. Which you can use to select a single field, eg:

var q = db.From<Table>().Select(x => x.Name);

Multiple fields:

var q = db.From<Table>().Select(x => new { x.Id, x.Name });

Or fields with aliases:

var q = db.From<Table>().Select(x => new { x.Id, OtherName = x.Name });

It's not for specifying which model it should project to, that happens when you execute the query, eg:

var results = db.Select<MyPocoAlias1>(q);

Which will map the returned result set (eg SELECT Id, Name AS "OtherName") into the MyPocoAlias1 POCO.

in your code

var q1 = Db.From() .Select(c => new MyPocoAlias1 { OtherName = c.Name })

This is the way we use anonymous types. delete your class MyPocoAlias1 because it is not needed. You have used anonymous type but you have named it. change that to

var q1 = Db.From<MyPoco1>()
    .Select(c => new { OtherName = c.Name })

And instead of OtherName you can use anything you want.

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