1
votes

..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.CompanyName).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.

2
That's a terrible title for a question - imagine someone trying to find this in the future.kͩeͣmͮpͥ ͩ
I don't think that stackoverflow's own search is very good, I think people find answers using google -- that is how they intended it to be at stack overflow...and I doubt the title will make much difference in google.the_law

2 Answers

1
votes

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.

0
votes

You need to specify the column name of Product.Id as ProductID

Most of what you're doing can be done with the AutoMapper