我有以下表格
Car(CarId, Name,...)
CarPartLink(CarId, PartId)
Part(PartId, Name)
SubPartLink(Parent_PartId, Child_PartId)
其中父母和子女都来自Part table 我希望Car
个对象包含Parts
的列表,其中包含SubParts
,此处Car
与其Part
Subparts
没有直接关系Part
与Subparts
没有直接关系。
即
class Car
{
public virtual string Id { get; set; }
public virtual string Name { get; set; }
public virtual ICollection<Parts> AllParts { get; set; } //This should include all the parts and its subparts assuming subparts are only one level deep
}
如何在Fluent NHibernate中制作相同的地图?
修改1:
如果在Fluent NHibernate中不可能,但在NHibernate映射中可能,那么对我也没关系。
我使用的是Fluent NHibernate版本:1.4.0.1和NHibernate版本:3.3.3
编辑2:
如果我只获得地图中的id
个子部分或subparts
,我也很好。
编辑3:
每辆车(此处为Car
提及的示例)总共超过100万parts
和subparts
,其中用户实际上将使用少量100件,具体取决于条件。例如获取所有重量为100 kg的零件或获得所有“螺钉”类型的零件。我将在只读模式下需要这些数据。
答案 0 :(得分:1)
FluentNH wiki已经有关于关系映射的精彩教程。我建议你阅读指南,或者更好,一步一步地按照它。假设以下实体:
public class Car
{
public virtual int CarId { get; set; }
public virtual string Name { get; set; }
public virtual IList<Part> AllParts {get; set;}
public Car()
{
AllParts = new List<Part>();
}
}
public class Part
{
public virtual int PartId { get; set; }
public virtual string Name { get; set; }
public virtual IList<Car> AllCars {get; set;}
//never tried mapping a many-to-many on the same entity, but this should work...
public virtual IList<Part> ParentParts {get; set;}
public virtual IList<Part> SubParts {get; set;}
public Part()
{
AllCars = new List<Car>();
ParentParts = new List<Part>();
SubParts = new List<Part>();
}
}
你的映射可能是这样的:
public class CarMap : ClassMap<Car>
{
public CarMap()
{
Id(x => x.CarId);
Map(x => x.Name);
HasManyToMany(x => x.AllParts)
//depending on your logic, you would either set .Inverse here or in the PartMap
.Table("CarPartLink")
.ParentKeyColumn("CarId")
.ChildKeyColumn("PartId")
.Cascade.All();
}
}
public class PartMap : ClassMap<Part>
{
public PartMap()
{
Id(x => x.PartId);
Map(x => x.Name);
HasManyToMany(x => x.AllCars)
.Table("CarPartLink")
.ParentKeyColumn("PartId")
.ChildKeyColumn("CarId")
.Cascade.All();
HasManyToMany(x => x.ParentParts)
.Table("SubPartLink")
.ParentKeyColumn("Parent_PartId")
.ChildKeyColumn("Child_PartId")
.Inverse() //saving done from the child side of the relationship, right?
.Cascade.All();
HasManyToMany(x => x.SubParts)
.Table("SubPartLink")
.ParentKeyColumn("Child_PartId")
.ChildKeyColumn("Parent_PartId")
.Cascade.All();
}
}
如果以上情况不起作用,请告诉我。显然,某些版本的FNH中存在一个错误,您需要采用特殊的解决方法。您可以在this question中找到解决方法(通过OP查找自行提交的答案),该方法基于与您相同的方案(同一实体上的多个方案)。
编辑:如果您想获取Car
的所有部分和子部分,则需要递归访问每个SubParts
的{{1}}在您的Part
集合中。
Car.AllParts
Edit2 :这blog post似乎正是您所需要的......
Car Car1 = new Car();
//code to get car object
IList<Part> AllParts = new List<Part>();
GetAllParts(Car.AllParts, ref AllParts); //call a recursive method to add all the parts and subparts to the list
//do something with the list
public void GetAllParts(IList<Part> parentList, ref IList<Part> partsList)
{
foreach (Part part in parentList)
{
if (!partsList.Contains(part)) //validate if the list already contains the part to prevent replication
partsList.Add(part); //add this part to the list
if (part.SubParts.Count > 0) //if this part has subparts
GetSubParts(part.SubParts, ref partsList); //add all the subparts of this part to the list too
}
}