(Fluent) nHibernate: "As with References, the foreign-key defaults to Author_id, and you can override it
..with the KeyColumn method or change the default behaviour with a Convention. "
That quote is from the fluent nhibernate mapping guide. I can't understand why it does this instead of, for that example, using the correct (column) name for the Author class primary key.
I know one solution, which is to use .KeyColumn like it is here in my own mappings (my question is coming after this code):
public class SupplierMap : ClassMap<Supplier>
{
public SupplierMap()
{
Table("Suppliers");
LazyLoad();
Id(x => x.SupplierID, "SupplierID");
Map(x => x.Comp开发者_C百科anyName).Not.Nullable();
Map(x => x.ContactName);
Map(x => x.ContactTitle);
Map(x => x.Address);
Map(x => x.City);
Map(x => x.Region);
Map(x => x.PostalCode);
Map(x => x.Country);
Map(x => x.Phone);
Map(x => x.Fax);
Map(x => x.HomePage);
HasMany(x => x.Products).KeyColumn("ProductID").Inverse().Cascade.All();
}
}
And the Product mapping is:
public class ProductMap : ClassMap<Product>
{
public ProductMap()
{
Table("Products");
LazyLoad();
Id(x => x.ProductID);
References(x => x.Supplier, "SupplierID");
Map(x => x.ProductName).Not.Nullable();
Map(x => x.QuantityPerUnit);
Map(x => x.UnitPrice);
Map(x => x.UnitsInStock);
Map(x => x.UnitsOnOrder);
Map(x => x.ReorderLevel);
Map(x => x.Discontinued).Not.Nullable();
}
}
So my question is, is there a more elegant way? I was quite disappointed to see two columns on my product table for id (ProductID and Product_ID). As mentioned this was fixed with KeyColumn("ProductID") as above. Is there a way I can set this in the Product mapping, or even in the configuration? I don't think I understand the "override the default behaviour with a convention" -- that is probably where the answer is.
First off, if your FKs are all in that format ObjectNameID
then you probably want to do a custom FK convention:
public class CustomForeignKeyConvention : ForeignKeyConvention
{
protected override string GetKeyName(Member property, Type type)
{
if (property == null)
return type.Name + "Id";
return property.Name + "Id";
}
}
That should preclude you from having to specify the FK name manually. You can also do a PK convention if you're not using Id
as the property name for your PKs.
public class PrimaryKeyConvention : IIdConvention
{
public void Apply(IIdentityInstance instance)
{
instance.Column(instance.EntityType.Name + "Id");
}
}
(from the FNH docs)
I suspect your use of a PK convention that doesn't match FNH's expectations is your issue in this case.
You need to specify the column name of Product.Id
as ProductID
Most of what you're doing can be done with the AutoMapper
精彩评论