chobo2
chobo2

Reputation: 85715

Few questions about nhibernate & fluent nhibernate

I have a couple questions.

  1. I been reading in nhibernate beginners guide 3 about using auto mapper with fluent. I read about this before(and I use auto mapper in my project already) however I am still not sure about a couple things.

What happens when you need to put like Not.Null(), or have to set a length, or inverse on something. How do you set those up? Won't you have to setup auto mapper for each of these properties that have these settings? Won't that sort of default the purpose?

  1. I also been reading about common mistakes and one mistake was talking about when you need readonly. I am actually suffering from this problem and had to make a fix that I was never that happy about.

From reading this I am wondering if it is wise to have 2 mappings of these classes that I need to have readonly

Say I have this

   public PlanMap()
        {
            Table("Plans");
            Id(x => x.Id);

            Map(x => x.Name).Not.Nullable().NvarcharWithMaxSize();
            Map(x => x.Description).Not.Nullable().NvarcharWithMaxSize();
            Map(x => x.Price).Not.Nullable();
            Map(x => x.Discount).Not.Nullable();
            Map(x => x.LengthInMonths).Not.Nullable();

            References(x => x.Role).Not.Nullable();
            HasMany(x => x.Students).Cascade.All();

        }

So would it be wise to have that and then have

    public ReadOnlyPlanMap()
    {
        Table("Plans");


        ReadOnly();
        SchemaAction.None();


        Id(x => x.Id);
        Map(x => x.Name).Not.Nullable().NvarcharWithMaxSize();
        Map(x => x.Description).Not.Nullable().NvarcharWithMaxSize();
        Map(x => x.Price).Not.Nullable();
        Map(x => x.Discount).Not.Nullable();
        Map(x => x.LengthInMonths).Not.Nullable();

        References(x => x.Role).Not.Nullable();
        HasMany(x => x.Students).Cascade.All();

    }

Then when I need ReadOnly I use that mapping when I don't I use the other mapping? The only thing I see wrong about this is duplicate code. I am not sure if I can use inheritance or something to solve that problem though.

3.I read in the book that it recommend not to use the "auto" incrementing option in your database but instead use a hi-lo one setup in nhibernate to handle this.

In the book it says if you did something like session.Save(object); it would actually go and contact the server and this would break the unit of work. Does this happen when "auto" incrementing is set on the database? I never saw evidence of that happening and actually I had to commit a record before I would actually see the id.

When you use hi-lo what datatype does your column have to be? I usually use for my pk a incrementing int. Can I still use a int?

  1. Finally from alot of examples I seen they usually make their PK properties like this

    public virtual int Id { get; private set; }
    

Yet in the book I constantly saw

    public virtual int Id { get; set; }

I thought using private set was the way to go to stop people from making their own number for the PK.

Upvotes: 0

Views: 228

Answers (1)

joshperry
joshperry

Reputation: 42227

You would have better luck getting all of your questions answered if you broke them up into separate questions, but I'll address a couple of your questions anyway:

Automapping, Custom Conventions, and Overrides

If one of your business requirements is that most properties should not be nullable then you should make that the default by providing your own convention to the automapper. Take a look at this blog post for how you can do this.

Then if you have a mapping that needs to differ slightly from your conventions, then you can provide an automapping override by implementing IAutoMappingOverride<T> where in you only specify the columns/ids/relationships that are aberrant to the conventions.

The documentation at the FluentNHibernate wiki on Overrides and Conventions is actually quite good, I highly recommend reading it.

Readonly Entities

If I was doing this, what I'd do is have an NHibernate ignored, internal set property called something like IsReadonly { get; internal set; }, when an object is retrieved from somewhere that it should be read-only, then set that property before returning it to the caller.

If you have an explicit Save method on a repository, you can check that property and not do the actual NHibernate save if it's true. If you rely on the NHibernate dirty checking for saving on session Flush then you could implement an NHibernate listener which would not save the entity if that property was true.

Identifiers

One word (acronym) GUID; hi-lo can work, but it can get complicated and a bit finicky. For NHibernate to properly track the object it has to have a unique ID. If you're using auto ids then NHibernate will go to the database to get an ID when you Save your entity and before you do the Flush.

Comb GUIDs solve the problems that you'll run into with auto ids and hi-lo in exchange for taking a little bit more space in your DB, and memory. When using FluentNHibernate automapping, if your entity has a GUID as the type of it's Id property, it will automatically use the Guid Comb strategy.

Upvotes: 2

Related Questions