私はこれらのクラスを持っています:
class Car {
int ID;
string Name;
}
class Truck : Car {
int MaximumLoad;
}
私はこれらのテーブルを持っています
Car
- ID
- Name
Truck
- CarID
- MaximumLoad
PetaPoco を使用してクラスをテーブルにマップするにはどうすればよいですか?
CarとTruckを同じテーブル(TPH)に保存すると、PetaPOCOソースコードに小さな変更を加えてCarからTruckを継承できます。
テーブル車両(ID、ディスクリミネーター、名前、MaximumLoad)
PetaPOCO.csに、追加します
[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.
次に、Car.csとTruck.csで、次のようなコードを記述/生成できます。
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 つのテーブルを結合する Trucks ビューを作成します。または、Schotime の複数の結果セットをご覧ください。
http://schotime.net/blog/index.php/2011/11/20/petapoco-multiple-result-sets/
書き込みについては、「1回の操作で2つのテーブルに書き込む方法」を尋ねていると思います。頭のてっぺんから、おそらく2回の書き込みを実行するだけだと思います。Petapoco はマップされていないフィールドを無視するので、両方の書き込みにトラック オブジェクトを使用できると思います。
私はこれをテストしていないので、簡単に間違っている可能性があります。
私はあなたがこのようなことをするなら(しかしテストしていません)と思います。
repo.Fetch<Truck>(";Select car.*, truck.maximumload from car left join truck on car.id = truck.carid");
また
repo.Fetch<Truck>(";Select car.*, truck.maximumload from car left join truck on car.id = truck.carid where truck.carid = @0", truckid);
車ではなくベースクラスの車と呼んでいたかもしれませんが、それは私だけです。
それがお役に立てば幸いですか?