Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
asherber opened this issue Jun 30, 2021 · 1 comment
Open

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

asherber opened this issue Jun 30, 2021 · 1 comment

Comments

@asherber
Copy link
Collaborator

asherber commented Jun 30, 2021

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; }
}
@Ste1io
Copy link
Collaborator

Ste1io commented May 17, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants