PetaPoco icon indicating copy to clipboard operation
PetaPoco copied to clipboard

Multi-Poco queries don't like non-public poco classes

Open asherber opened this issue 3 years ago • 1 comments

PetaPoco in general works just fine with non-public classes, but I have discovered that multi-poco queries do not. I don't know much about IL generation, but I'm pretty sure it has to do with the function generated by MultiPocoFactory.CreateMultiPocoFactory(), especially the calls to Invoke().

Here's a LinqPad script using an in-memory SQLite db. It runs just fine as is, but if you change the access modifiers on the User and Article classes, you'll get an exception: MethodAccessException: Attempt by method 'DynamicClass.petapoco_multipoco_factory(PetaPoco.Internal.MultiPocoFactory, System.Data.IDataReader, System.Object)' to access method 'System.Func`2<System.__Canon,System.__Canon>.Invoke(System.__Canon)' failed.

void Main()
{
    var config = DatabaseConfiguration.Build()
        .UsingConnectionString("Data Source=:memory:")
        .UsingProvider<SQLiteDatabaseProvider>();

    using (var db = new Database(config))
    {
        db.KeepConnectionAlive = true;

        db.Execute("CREATE TABLE IF NOT EXISTS User (ID INTEGER PRIMARY KEY, Name TEXT)");
        db.Execute("CREATE TABLE IF NOT EXISTS Article (ID INTEGER PRIMARY KEY, UserID, INTEGER, Title TEXT)");

        db.Insert("User", new { Name = "Bob" });
        db.Insert("User", new { Name = "Jane" });        
        db.Insert("Article", new { UserID = 1, Title = "Epidemiology" });
        db.Insert("Article", new { UserID = 1, Title = "Astronomy" });
        db.Insert("Article", new { UserID = 2, Title = "Art" });
        db.Insert("Article", new { UserID = 2, Title = "Soccer" });

        var q = "select u.id, u.name, a.userid, a.title from user as u inner join article as a on u.id=a.userid";
        var recs = db.Fetch<User, Article>(q).Dump();
    }
}


public class User
{
    public int ID { get; set; }
    public string Name { get; set; }
    public Article Article { get; set; }
}

public class Article
{
    public string Title { get; set; }
}

asherber avatar Jun 30 '21 00:06 asherber

It runs just fine as is, but if you change the access modifiers on the User and Article classes, you'll get an exception

Can you provide the changed version that throws an exception? I'm unable to repro it. When testing with

public class User
{
	public int ID { get; set; }
	public string Name { get; set; }
	internal Article Article { get; set; }
}

internal class Article
{
	public string Title { get; set; }
}

It throws this exception, but that's the closest I got to what you're mentioning (and not unhandled).

And with

internal class User
{
	public int ID { get; set; }
	public string Name { get; set; }
	public Article Article { get; set; }
}

public class Article
{
	public string Title { get; set; }
}

everything runs as expected.

Ste1io avatar May 17 '23 04:05 Ste1io