James,
One other thing that deserves mentioning is the IdentityIdConvention.
It accepts anything that isn't accepted by the
AssignedIdentityConvention like so:
public class IdentityIdConvention : IIdConvention
{
public bool Accept(IIdentityPart target)
{
return target.IdentityType == typeof (int) &!
(new AssignedIdConvention()).Accept(target);
}
public void Apply(IIdentityPart target)
{
target.GeneratedBy.Identity();
}
}
Assuming you don't think this use case is garbage it would be useful to
have a static method available for conventions to check whether a target
would be accepted.
The above code could then be modified as follows:
public class IdentityIdConvention : IIdConvention
{
public bool Accept(IIdentityPart target)
{
return target.IdentityType == typeof (int) &!
AssignedIdConvention.Accepts(target);
}
public void Apply(IIdentityPart target)
{
target.GeneratedBy.Identity();
}
}
Thoughts?
From: [email protected]
[mailto:[email protected]] On Behalf Of Martin
Hornagold
Sent: 25 March 2009 16:27
To: [email protected]
Subject: [fluent-nhib] Re: .WithTable in IAutoMappingOverride doesn't
override IClassConvention
James/Billy,
Attached is a patch with my take on the conventions in Northwind example
in S#arp Architecture (patched to revision 420).
James,
I would be particularly interested on your views and how you would
approach it.
There are a couple of overrides still remaining.
The EmployeeTerritories many to many is a stumbling block. I feel that
this should be a convention but not really sure how to achieve it.
See my comment in the ManyToManyTableNameConvention class for details:
public class ManyToManyTableNameConvention : IHasManyToManyConvention
{
public bool Accept(IManyToManyPart target)
{
return true;
}
public void Apply(IManyToManyPart target)
{
// want to be able to do something like the following to
// account for the EmployeeTerritories case:
// var tableName = target.IsInverse
// ?
// target.ChildType.Name +
Inflector.Net.Inflector.Pluralize(target.EntityType.Name)
// :
// target.EntityType.Name +
Inflector.Net.Inflector.Pluralize(target.ChildType.Name);
// target.WithTableName(tableName);
}
}
Cheers,
Martin
From: [email protected]
[mailto:[email protected]] On Behalf Of James Gregory
Sent: 25 March 2009 14:07
To: [email protected]
Subject: [fluent-nhib] Re: .WithTable in IAutoMappingOverride doesn't
override IClassConvention
The difference is, you are overriding conventions but you're using an
automapping override, which is for overriding how a class is automapped
- not the same thing. It's a side-effect of how automapping is designed
that you can use an automapping override as the same thing as a
conventional override, but it's certainly not designed with that in
mind; one day when I've got my benevolent dictator hat on I may fix that
issue.
Why do you have to think in terms of a specific entity? It's been a long
time since I looked at Northwind, but surely there are a collection of
conventions rather than one convention with a single override. You
shouldn't think of it as changing a single entity, but all the entities
that match that style.
The conventions are designed using interfaces, so if you really do want
just one class to be altered, then create a MyEntityOverrideConvention
class that implements all the interfaces it needs to change.
public class CustomerOverrides : IClassConvention, IIdConvention
{
public bool Accept(IClassMap target)
{
return Accept(target.EntityType);
}
public bool Accept(IIdentityPart target)
{
return Accept(target.EntityType);
}
private bool Accept(Type type)
{
return type == typeof(Customer);
}
public void Alter(IClassMap target)
{
target.WithTable("FunnyCustomerTableName");
}
public void Alter(IIdentityPart target)
{
target.ColumnName("IdSpecialName");
}
}
On Wed, Mar 25, 2009 at 1:38 PM, Billy <[email protected]>
wrote:
But to me, an override should do just that: "override." Accordingly,
you can have a "convention" which may get "overridden" on a case by
case basis. Let's assume that I have one object which doesn't adhere
to many conventions. (Granted, this is a bad design, but it certainly
comes up with legacy databases.) Accordingly, I'll have to put an
explicit class and/or property exclusion into a number of convention
classes. To me, that smells of shotgun surgery and doesn't allow one
to nicely encapsulate the overrides in one location. E.e., if the
mapping rules for a customer object changes, which aren't in
compliance with the conventions, then I would expect that I should
only have to look at the customer overrides to make a modification to
the mapping rules. Otherwise, I'm going to have to do a project-wide
find of all the customer exclusions to find the right one to modify.
Billy
On Mar 25, 4:41 am, "Martin Hornagold"
<[email protected]> wrote:
> Billy,
>
> I agree with James.
>
> The beauty of the new conventions system is that you can selectively
> apply conventions to classes.
>
> I notice from your comment about class exclusions and your comments in
> the PrimaryKeyConvention class in S#arp that you seem to be shying
away
> from this.
>
> I have been battling with how to apply conventions/overrides within my
> project and am now leaning towards James' approach of targeted
> conventions with prescriptive class names .
>
> So in S#arp's Northwind sample we should have:
>
> IdentityIdConvention
>
> AssignedStringIdConvention
>
> Rather than just PrimaryKeyConvention
>
> We should have Pluralized and Singular table name conventions.
>
> There should also Lazy and NonLazy class conventions which would again
> reduce the need for overrides and are more maintainable.
>
> Just my 2 pennies
>
> Martin
>
> From: [email protected]
> [mailto:[email protected]] On Behalf Of James Gregory
> Sent: 25 March 2009 10:02
> To: [email protected]
> Subject: [fluent-nhib] Re: .WithTable in IAutoMappingOverride doesn't
> override IClassConvention
>
> Ah, damn. I can't re-order them. The conventions can't be applied
before
> the overrides because the overrides may alter the underlying classmap,
> which could result in some conventions not being applied when they
> should be.
>
> I'd go with my previous suggestion of doing this exclusively with
> conventions. You've got a few options: you could have your
> TableNameConvention and a RegionTableNameConvention, or a
> PluralizedTableNameConvention and a SingularTableNameConvention, or
> perhaps a Plural attribute that you decorate specific entities with.
>
> Let me know what you think of this.
>
> On Wed, Mar 25, 2009 at 9:56 AM, James Gregory
<[email protected]>
> wrote:
>
> Just looked into this, it seems overrides are being applied before
> conventions. So the changes get overwritten by the conventions... The
> thread you linked to is a bit of a bigger issue, but for this one I
> should just be able to reorder when the overrides get applied.
>
> An alternative is to not use overrides at all for this situation, as
> you're not actually doing anything with the automappings. You could
just
> write another convention that's RegionTableNameConvention.
>
> Still, I'll fix this either way.
>
> On Tue, Mar 24, 2009 at 8:29 PM, James Gregory
<[email protected]>
> wrote:
>
> Yep, something smelly is going on here. I'll investigate.
>
> On Tue, Mar 24, 2009 at 8:13 PM, Billy <[email protected]> wrote:
>
> Looks like this is related to the issue described
athttp://groups.google.com/group/fluent-nhibernate/browse_thread/thread/
b8
> 66ce932b2a4f89
>
> Incidentally, if I modify the class convention to ignore the Region
> class, then the override works just fine; e.g.,
>
> public class TableNameConvention : IClassConvention
> {
> public bool Accept(IClassMap classMap) {
>
> return classMap.EntityType != typeof(Region);
>
> }
>
> public void Apply(IClassMap classMap) {
> classMap.WithTable(Inflector.Net.Inflector.Pluralize
> (classMap.EntityType.Name));
> }
>
> }
>
> But preferably, I don't want to have to put class exclusions within
> the convention classes, I'd rather have the overrides always take
> precedence.
>
> Billy
>
> On Mar 24, 2:07 pm, Billy <[email protected]> wrote:
>
> > Hi James,
>
> > I'm updating S#arp Architecture's example project to the last and
have
> > made great progress. In fact, the thing remaining is a problem I'm
> > having with an override not "taking."
>
> > I have the following class convention:
>
> > public class TableNameConvention : IClassConvention
> > {
> > public bool Accept(IClassMap classMap) {
> > return true;
> > }
>
> > public void Apply(IClassMap classMap) {
> > classMap.WithTable(Inflector.Net.Inflector.Pluralize
> > (classMap.EntityType.Name));
> > }
>
> > }
>
> > I then have an override for a Region class as follows:
>
> > public class RegionMap : IAutoMappingOverride<Region>
> > {
> > public void Override(AutoMap<Region> mapping) {
> > mapping.WithTable("Region");
> > ...
> > }
>
> > }
>
> > The .WithTable in the override is not getting applied, although the
> > other settings within the override are being applied just fine.
When
> > I do a select for any region objects, the SQL is trying to query a
> > table named Regions (which is compliant with the convention, but not
> > with the override).
>
> > Ideas?
>
> > Thanks!
> > Billy McCafferty
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Fluent NHibernate" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/fluent-nhibernate?hl=en
-~----------~----~----~----~------~----~------~--~---