I am trying to use fluent nHibernate to map a class that only exists as a container for other classes, and doesn't have an Id of its own. But I want the Id of the class to be a different class. That really doesn't make sense, it might be easier to explain with an example data structure.
abstract QueryBuilder
{
public IEnumerable<string> Category1Keys {get; set;}
public IEnumerable<int> Category2Ids {get; set;}
public IEnumerable<int> Category3Ids {get; set;}
}
Set
{
public int Id {get; set;}
public string Name {get; set;}
public SetQueryBuilder QueryBuilder{get; set;}
}
SetQueryBuilder : QueryBuilder
{
}
News
{
public int Id {get; set;}
public string Name {get; set;}
public NewsQueryBuilder QueryBuilder{get; set;}
}
NewsQueryBuilder : QueryBuilder
{
}
Now the QueryBuilder is the name is a concept that we use to map various (unrelated) items to the same categories. So things that might use QueryBuidler are News, Pages, Permissions.
Becuase all the various items that use QueryBuilder map that relationship in the same way, and ocasionally we actually use the paramters from one type of QueryBuilder as a the select criteriea for another type of QueryBuilder (ie if news has QB of A, get all the Sets that match the same criteria), I want to have a abstract QueryBuilder class, and then extend it for all the things that have mappings to all the categories.
Here is an example of the Set DB for query builder. There isn't an actual item in the DB for QueryBuilder - its composed of all the info from the category class join tables.
f_set
{
set_id (PK, int)
name (varchar)
}
f_set_cat1
{
set_id (PK, FK, int)
cat1_key (PK, FK, char(3))
}
f_set_cat2
{
set_id (PK, FK, int)
cat2_id (PK, FK, int)
}
f_set_cat3
{
set_id (PK, FK, int)
cat3_id (PK, FK, int)
}
My problem is how to map each instance of the QueryBuilder class in nHibernate, as it doesnt' have a real key or table entry, I would like to say that the Id is a reference to the Set that all the category mappings use.
Here are my fluent mappings so far:
SetMapping : ClassMap<Set>
{
public SetMapping()
{
Schema("cam");
Table("f_set");
Id(x => x.Id, "f_set_id").Gener开发者_开发技巧atedBy.Identity();
Map(x => x.Name, "name").Not.Nullable();
HasOne<SetQueryBuilder>(x => x.QueryBuilder);
}
}
SetQueryBuilderMapping : ClassMap<SetQueryBuilder>
{
public SetQueryBuilderMapping()
{
References(x => x.Set, "set_id");
HasMany(x => x.Category1Keys).Table("f_set_cat1").Element("cat1_key").KeyColumn("set_id");
HasMany(x => x.Category2Ids).Table("f_set_cat2").Element("cat2_id").KeyColumn("set_id");
HasMany(x => x.Category2Ids).Table("f_set_cat3").Element("cat3_id").KeyColumn("set_id");
}
}
Any help with the final step of the mapping would be hugely appreciated Thanks Saan
FURTHER INVESTIGATION Ok I have done a bit mroe investigating on this and have foudn that combining the two classes works fine if I do this:
CLASS:
Set
{
public int Id {get; set;}
public string Name {get; set;}
//public SetQueryBuilder QueryBuilder{get; set;}
public IEnumerable<string> Category1Keys {get; set;}
public IEnumerable<int> Category2Ids {get; set;}
public IEnumerable<int> Category3Ids {get; set;}
}
MAPPING
SetMapping : ClassMap<Set>
{
public SetMapping()
{
Schema("cam");
Table("f_set");
Id(x => x.Id, "f_set_id").GeneratedBy.Identity();
Map(x => x.Name, "name").Not.Nullable();
//HasOne<SetQueryBuilder>(x => x.QueryBuilder);
HasMany(x => x.Category1Keys).Table("f_set_cat1").Element("cat1_key").KeyColumn("set_id");
HasMany(x => x.Category2Ids).Table("f_set_cat2").Element("cat2_id").KeyColumn("set_id");
HasMany(x => x.Category2Ids).Table("f_set_cat3").Element("cat3_id").KeyColumn("set_id");
}
}
When doing nHibernate mappings this makes perfect sense, but I would really like to have all the category mappings in the separate SetQueryBuilder class.
Thanks again for any help Saan
You are looking for subclassing strategy. Take a look at this http://nhibernate.info/doc/nh/en/index.html#inheritance
You probably want to follow a table per class with table per subclass strategy imo.
精彩评论