views:

208

answers:

3

I like the pattern I saw in this blog post (http://marekblotny.blogspot.com/2009/04/conventions-after-rewrite.html), where the author is checking to see if a table name alteration has already been made before applying a convention.

public bool Accept(IClassMap target)
{
    //apply this convention if table wasn't specified with WithTable(..) method
    return string.IsNullOrEmpty(target.TableName);
}

The convention interface I'm using for a string length is IProperty:

public class DefaultStringLengthConvention: IPropertyConvention
{
    public bool Accept(IProperty property) {
        //apply if the string length hasn't been already been specified
        return ??; <------ ??
    }

    public void Apply(IProperty property) {
        property.WithLengthOf(50);
    }
}

I don't see where IProperty exposes anything that tells me if the property has already been set. Is this possible?

TIA, Berryl

+1  A: 

.WithLengthOf() adds an "alteration" (Action<XmlElement>) to the list of alterations to apply when the XML mapping is generated. Unfortunately, that field is private and there is no property to access the alteration list, so I'm afraid there is (currently) no way to check if a property map has had WithLengthOf applied to it.

Stuart Childs
thought that might be the deal; I don't mind adding conventions for groups of string lengths but many cases are one-offs that are really driven by the class. So if an EmployeeNumber string length should be 6 chars it's either EmployeeNumberStringLengthConvention for the one field or an if statement in the DefaultStringLengthConvention.Thx for the quick response.
Berryl
+1  A: 

Until a better alternative comes along, you can use HasAttribute("length").

James Gregory
That would be good enough, but it doesn't work. I haven't updated FNH in a few weeks - is that a recent update? Could the attribute be something other than "length"?Thanks for the reply.
Berryl
Berryl, HasAttribute should work if you use SetAttribute. As of revision 458, WithLengthOf stores the "length" attribute in a collection called columnProperties. SetAttribute stores in extendedProperties, which is also where HasAttribute looks. SetAttribute/HasAttribute have worked this way for as long as I can tell so it will probably work with whatever version you are using.
Stuart Childs
A: 

To clarify in code what Stuart and Jamie are saying, here's what works:

public class UserMap : IAutoMappingOverride<User>
{
    public void Override(AutoMap<User> mapping) {
        ...
        const int emailStringLength = 30;
        mapping.Map(x => x.Email)
            .WithLengthOf(emailStringLength)                        // actually set it
            .SetAttribute("length", emailStringLength.ToString());  // flag it is set
        ...

    }
}

public class DefaultStringLengthConvention: IPropertyConvention
{
    public bool Accept(IProperty property) {
        return true;
    }

    public void Apply(IProperty property) {
        // only for strings
        if (!property.PropertyType.Equals(typeof(string))) return;

        // only if not already set
        if (property.HasAttribute("length")) return;

        property.WithLengthOf(50);
    }
}
Berryl