現在的Linq To Sql只支持單表繼承,不支持一實體一具體表和一實體一擴展表等方式繼承。什麼是單 表繼承呢?所謂單表繼承就是把整個繼承體系存儲在數據庫的一個表中。由此可以知道,這個表結構包括 所有實體的屬性字段,如果在該繼承體系中,實體的數量較多,就會產生大量的null值的數據,這樣浪費 了很多的數據存儲空間。不過所有的繼承體系放在一個表中,邏輯簡單容易操作,數據量不大的時候效率 也高。下面看看在Linq To Sql中是怎樣實現單表繼承的(用Orcas白皮書中的示例來說明)。
假如現在有這樣一張表Vehicle,表結構如下:
它表示了三個實體:
Vehicle--基類,包含字段VIN、Key、MfgPlant
Car--Vehicle的派生類,擴展字段TrimCode、ModelName
Truck--Vehicle的派生類,擴展字段Tonnage、Axles
其中Key是用來標志該行是表示什麼類型的實體,如果該行表示Vehicle,則值為"V",如果表示Car,值 為"C"。
下面的示例表示該繼承體系是怎樣映射到數據庫的表Vehicle中的(這裡使用Column Attribute映射字 段)
[Table]
[InheritanceMapping(Code = "V", Type = typeof(Vehicle),
IsDefault=true)]
[InheritanceMapping(Code = "C", Type = typeof(Car))]
[InheritanceMapping(Code = "T", Type = typeof(Truck))]
public class Vehicle
{
[Column(IsDiscriminator = true)]
public string Key;
[Column(IsPrimaryKey = true)]
public string VIN;
[Column]
public string MfgPlant;
}
public class Car : Vehicle
{
[Column]
public int TrimCode;
[Column]
public string ModelName;
}
public class Truck : Vehicle
{
[Column]
public int Tonnage;
[Column]
public int Axles;
}
可以看到,在Vehicle類上,對於在繼承體系中的每個類都使用了InheritanceMapping Attribute。其 中定義了Code Property,它與Vehicle類中的key字段相對應,因為Key字段用了IsDiscriminator來標志 ,它說明這個字段保存著映射的Code值。 Type Property表示該Code值對應哪個類型,如"V"--Vehicle, "C"--Car。 IsDefault設置為true的話,表示如果數據表中的Key值不滿足其中任意一個(比如"A",不滿 足定義的"V","C","T"),都用該類型表示(Vehicle)。 所有子類子需要映射字段,不再需要映射數據 表了(不用加上Table Attribute)。 下面是類圖:
我們怎樣取各種實體呢?看看下面的代碼:
[Database(Name="MyDatabase")]
public class VehicleContext : DataContext
{
......
public Table<Vehicle> Vehicls
{
get
{
return this.GetTable<Vehicle>();
}
}
public IQueryable<Truck> Trucks
{
get {
return this.Vehicls.OfType<Truck>();
}
}
public IQueryable<Car> Cars
{
get
{
return this.Vehicls.OfType<Car>();
}
}
}
白皮書中還舉例說明了其他的方式,比如
return this.Vehicls.Where(p => p is Car);
或者
return this.Vehicls.Select(p => p as Car).Where(p => p != null);
只支持單表繼承體系的確是很初級,不過從Linq To Sql的功能上來看,它主要強調的是從編譯以及語 言層面上來支持數據查詢和分析,而不是強大的ORM,如果想要實體繼承、支持多數據庫、松散耦合,可 以使用Linq To Entites或者ADO.NET Entity Framework。可以說Linq To Sql的出現給.NET編程人員帶來 了極大的驚喜。