How to map childs/parent class with petapoco?

北城余情 提交于 2019-12-24 06:25:37

问题


I have these classes:

class Car {
    int ID;
    string Name;
}

class Truck : Car {
    int MaximumLoad;
}

I have these tables

Car
- ID
- Name

Truck
- CarID
- MaximumLoad

How could I map my classes with my table using PetaPoco ?


回答1:


If you store Car and Truck in the same table (TPH) you can inherit Truck from Car with minor changes to PetaPOCO source code,

table Vehicle (ID, Discriminator, Name, MaximumLoad)

in PetaPOCO.cs, add

[AttributeUsage(AttributeTargets.Class)]
public class DiscriminatorAttribute : Attribute
{
    public int Value { get; private set; }
    public DiscriminatorAttribute(object discriminator)
    {
        Value = (int)discriminator;
    }
}

protected bool IsTPHTable<T>()
{
    var t = typeof(T);
    var a = t.GetCustomAttributes(typeof(DiscriminatorAttribute), true);
    return a.Length > 0;
}

protected void AppendDiscriminator<T>(Sql sql)
{
    var t = typeof(T);
    var a = t.GetCustomAttributes(typeof(DiscriminatorAttribute), true);
    sql.Append("Where Discriminator = @0", (a[0] as DiscriminatorAttribute).Value);
}

public IEnumerable<T> Query<T>(Sql sql)
{
    if (IsTPHTable<T>())
        AppendDiscriminator<T>(sql);
    return Query<T>(default(T), sql);
}

// also similar AppendDiscriminator() for Update an Delete.

Then in your Car.cs and Truck.cs, you can write/generate code like this,

public enum VehicleType:int
{
    Car,
    Truck
}

[TableName("Vehicle")]
[Discriminator(VehicleType.Car)]
public class Car  
{
    [Column] 
    public int ID {get; set;}
    [Column]
    public string Name {get; set;}

    public Car()
    {
        //this.Discriminator = VehicleType.Car;
    }
    public static new Car SingleOrDefault(object primaryKey) { return repo.SingleOrDefaultById<Car>(primaryKey); }
    //...
}

[Discriminator(VehicleType.Truck)]
public class Truck:Car  
{
    [Column] 
    public double MaximumLoad {get;set;}

    public Truck()
    {
        //this.Discriminator = VehicleType.Truck;
    }   
    public static new Truck SingleOrDefault(object primaryKey) { return repo.SingleOrDefaultById<Truck>(primaryKey); }
    //...
}



回答2:


To read truck records I would create a Trucks view that combines the two tables. Or have a look at Schotime's muliple result sets :

http://schotime.net/blog/index.php/2011/11/20/petapoco-multiple-result-sets/

For writes I guess you are asking "how can I write to 2 tables in one operation". Off the top of my head I would probably say I would simply perform 2 writes. I think Petapoco will ignore fields that don't map so you may be able to use your truck object for both writes.

Could easily be wrong as I haven't tested this.




回答3:


I think (have not tested though) that if you do something like this..

repo.Fetch<Truck>(";Select car.*, truck.maximumload from car left join truck on car.id = truck.carid");

or

repo.Fetch<Truck>(";Select car.*, truck.maximumload from car left join truck on car.id = truck.carid where truck.carid = @0", truckid);

I would probably have called my base class vehicle rather than car, buts that's just me.

Hope that helps ?



来源:https://stackoverflow.com/questions/8344591/how-to-map-childs-parent-class-with-petapoco

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!