Skip to content

Commit

Permalink
Applied fluent_nh.patch from Ayende.
Browse files Browse the repository at this point in the history
1) it automatically detect if we should use <set> or <bag>
2) it now recognize <many-to-many> associations.

git-svn-id: https://fluent-nhibernate.googlecode.com/svn/trunk@144 48f0ce17-cc52-0410-af8c-857c09b6549b
  • Loading branch information
jagregory committed Dec 11, 2008
1 parent ac0bdbd commit 794be94
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 21 deletions.
29 changes: 29 additions & 0 deletions src/FluentNHibernate.Testing/AutoMap/AutoMapTests.cs
Expand Up @@ -3,6 +3,7 @@
using FluentNHibernate.AutoMap;
using FluentNHibernate.AutoMap.TestFixtures;
using FluentNHibernate.Testing;
using FluentNHibernate.Testing.AutoMap.ManyToMany;
using FluentNHibernate.Testing.DomainModel.Mapping;
using NUnit.Framework;

Expand Down Expand Up @@ -86,6 +87,34 @@ public void AutoMapManyToOne()
keyElement.AttributeShouldEqual("name", "Parent");
}

[Test]
public void AutoMapManyToMany()
{
var autoMapper = new AutoMapper(new Conventions());
var map = autoMapper.Map<ManyToMany1>();

Assert.IsNotNull(map);

var document = map.CreateMapping(new MappingVisitor());

var keyElement = (XmlElement)document.DocumentElement.SelectSingleNode("//many-to-many");
keyElement.AttributeShouldEqual("column", "ManyToMany2_id");
}

[Test]
public void AutoMapManyToMany_ShouldRecognizeSet_BaseOnType()
{
var autoMapper = new AutoMapper(new Conventions());
var map = autoMapper.Map<ManyToMany1>();

Assert.IsNotNull(map);

var document = map.CreateMapping(new MappingVisitor());

var keyElement = (XmlElement)document.DocumentElement.SelectSingleNode("//many-to-many");
keyElement.ParentNode.Name.ShouldEqual("set");
}

[Test]
public void AutoMapOneToMany()
{
Expand Down
19 changes: 19 additions & 0 deletions src/FluentNHibernate.Testing/AutoMap/ManyToMany.cs
@@ -0,0 +1,19 @@
using Iesi.Collections.Generic;

namespace FluentNHibernate.Testing.AutoMap
{
namespace ManyToMany
{
public class ManyToMany1
{
public virtual int Id { get; set; }
public virtual ISet<ManyToMany2> Many1 { get; set; }
}

public class ManyToMany2
{
public virtual int Id { get; set; }
public virtual ISet<ManyToMany1> Many2 { get; set; }
}
}
}
4 changes: 3 additions & 1 deletion src/FluentNHibernate.Testing/AutoMap/TestFixtures.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System;
using Iesi.Collections.Generic;

namespace FluentNHibernate.AutoMap.TestFixtures
{
Expand Down Expand Up @@ -35,6 +36,7 @@ public class ExampleClass
public ExampleParentClass Parent { get; set; }
}


public enum ExampleEnum
{
enum1=1
Expand All @@ -46,4 +48,4 @@ public class ExampleParentClass
public virtual int Id { get; set; }
public virtual IList<ExampleClass> Examples {get; set;}
}
}
}
Expand Up @@ -34,7 +34,7 @@ public void CanSpecifyCollectionOfComponents()
new MappingTester<OneToManyComponentTarget>()
.ForMapping(m => m.HasMany<ComponentOfMappedObject>(x => x.SetOfComponents)
.Component(c => c.Map(x => x.Name)))
.Element("class/bag/composite-element").Exists();
.Element("class/set/composite-element").Exists();
}

[Test]
Expand Down Expand Up @@ -174,7 +174,7 @@ public void OneToManyElementIsExcludedForComponents()
new MappingTester<OneToManyComponentTarget>()
.ForMapping(m => m.HasMany<ComponentOfMappedObject>(x => x.SetOfComponents)
.Component(c => c.Map(x => x.Name)))
.Element("class/bag/one-to-many").DoesntExist();
.Element("class/set/one-to-many").DoesntExist();
}

[Test]
Expand All @@ -183,7 +183,7 @@ public void ShouldMapElementsOfCompositeElement()
new MappingTester<OneToManyComponentTarget>()
.ForMapping(m => m.HasMany<ComponentOfMappedObject>(x => x.SetOfComponents)
.Component(c => c.Map(x => x.Name)))
.Element("class/bag/composite-element/property[@name = 'Name']").Exists();
.Element("class/set/composite-element/property[@name = 'Name']").Exists();
}

[Test]
Expand All @@ -193,7 +193,7 @@ public void CanSetTableNameForCompositeElements()
.ForMapping(m => m.HasMany<ComponentOfMappedObject>(x => x.SetOfComponents)
.Component(c => c.Map(x => x.Name))
.WithTableName("MyTableName"))
.Element("class/bag").HasAttribute("table", "MyTableName");
.Element("class/set").HasAttribute("table", "MyTableName");
}

[Test]
Expand All @@ -211,7 +211,7 @@ public void SetsLazyLoadingAsDefault()
new MappingTester<OneToManyComponentTarget>()
.ForMapping(m => m.HasMany<ComponentOfMappedObject>(x => x.SetOfComponents)
.Component(c => c.Map(x => x.Name)))
.Element("class/bag").DoesntHaveAttribute("lazy");
.Element("class/set").DoesntHaveAttribute("lazy");
}

[Test]
Expand All @@ -223,7 +223,7 @@ public void SetsLazyLoadingOnThroughConvention()
new MappingTester<OneToManyComponentTarget>()
.UsingVisitor(visitor)
.ForMapping(m => m.HasMany<ComponentOfMappedObject>(x => x.SetOfComponents).Component(c => c.Map(x => x.Name)))
.Element("class/bag").HasAttribute("lazy", "true");
.Element("class/set").HasAttribute("lazy", "true");
}


Expand All @@ -233,7 +233,7 @@ public void SetsCascadeOffAsDefault()
new MappingTester<OneToManyComponentTarget>()
.ForMapping(m => m.HasMany<ComponentOfMappedObject>(x => x.SetOfComponents)
.Component(c => c.Map(x => x.Name)))
.Element("class/bag").DoesntHaveAttribute("cascade");
.Element("class/set").DoesntHaveAttribute("cascade");
}

[Test]
Expand All @@ -245,7 +245,7 @@ public void SetsCascadeOnThroughConvention()
new MappingTester<OneToManyComponentTarget>()
.UsingVisitor(visitor)
.ForMapping(m => m.HasMany<ComponentOfMappedObject>(x => x.SetOfComponents).Component(c => c.Map(x => x.Name)))
.Element("class/bag").HasAttribute("cascade", "all");
.Element("class/set").HasAttribute("cascade", "all");
}

[Test]
Expand Down Expand Up @@ -288,4 +288,4 @@ public void OneToManyMapping_with_private_backing_field()
.HasAttribute("name", "OtherChildren");
}
}
}
}
5 changes: 3 additions & 2 deletions src/FluentNHibernate.Testing/FluentNHibernate.Testing.csproj
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{F5DC3221-827E-4CB4-B61C-5F50EB4D32EA}</ProjectGuid>
<OutputType>Library</OutputType>
Expand Down Expand Up @@ -79,6 +79,7 @@
<Compile Include="AutoMap\AutoMappingTester.cs" />
<Compile Include="AutoMap\AutoMapTests.cs" />
<Compile Include="AutoMap\AutoPersistenceModelTests.cs" />
<Compile Include="AutoMap\ManyToMany.cs" />
<Compile Include="AutoMap\TestFixtures.cs" />
<Compile Include="Cfg\MsSqlConfigurationTester.cs" />
<Compile Include="Cfg\PersistenceConfigurationTester.cs" />
Expand Down Expand Up @@ -147,4 +148,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
8 changes: 5 additions & 3 deletions src/FluentNHibernate/AutoMap/AutoMapOneToMany.cs
Expand Up @@ -7,12 +7,14 @@ namespace FluentNHibernate.AutoMap
{
public class AutoMapOneToMany : IAutoMapper
{
private Func<PropertyInfo, bool> findPropertyconvention = p => (p.PropertyType.Namespace == "System.Collections.Generic");
private Func<PropertyInfo, bool> findPropertyconvention =
p => (p.PropertyType.Namespace == "System.Collections.Generic" ||
p.PropertyType.Namespace == "Iesi.Collections.Generic");

public bool MapsProperty(PropertyInfo property)
{
if (property.CanWrite)
return findPropertyconvention.Invoke(property);
return findPropertyconvention(property);

return false;
}
Expand All @@ -26,4 +28,4 @@ public void Map<T>(AutoMap<T> classMap, PropertyInfo property)
genericHasManyMethod.Invoke(classMap, new object[] { ExpressionBuilder.Create<T>(property) });
}
}
}
}
3 changes: 2 additions & 1 deletion src/FluentNHibernate/AutoMap/AutoMapper.cs
Expand Up @@ -17,6 +17,7 @@ public AutoMapper(Conventions conventions)
new AutoMapIdentity(conventions),
new AutoMapVersion(conventions),
new AutoMapColumn(conventions),
new ManyToManyAutoMapper(),
new AutoMapManyToOne(),
new AutoMapOneToMany(),
};
Expand Down Expand Up @@ -50,4 +51,4 @@ public AutoMap<T> Map<T>()
return MergeMap(classMap);
}
}
}
}
36 changes: 36 additions & 0 deletions src/FluentNHibernate/AutoMap/ManyToManyAutoMapper.cs
@@ -0,0 +1,36 @@
using System;
using System.Linq;
using System.Reflection;
using FluentNHibernate.Mapping;

namespace FluentNHibernate.AutoMap
{
public class ManyToManyAutoMapper : IAutoMapper
{
public bool MapsProperty(PropertyInfo property)
{
var type = property.PropertyType;
if (type.Namespace != "Iesi.Collections.Generic" &&
type.Namespace != "System.Collections.Generic")
return false;

var inverseSide = type.GetGenericTypeDefinition()
.MakeGenericType(property.DeclaringType);

var argument = type.GetGenericArguments()[0];
var hasInverse = argument.GetProperties()
.Where(x => x.PropertyType == inverseSide)
.Count() > 0;
return hasInverse;
}

public void Map<T>(AutoMap<T> classMap, PropertyInfo property)
{
var classMapType = typeof(ClassMap<T>);
var hasManyMethod = classMapType.GetMethod("HasManyToMany");
var listType = property.PropertyType.GetGenericArguments()[0];
var genericHasManyMethod = hasManyMethod.MakeGenericMethod(listType);
genericHasManyMethod.Invoke(classMap, new object[] { ExpressionBuilder.Create<T>(property) });
}
}
}
5 changes: 3 additions & 2 deletions src/FluentNHibernate/FluentNHibernate.csproj
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.21022</ProductVersion>
<ProductVersion>9.0.30729</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{1C988DFB-1EC5-484E-87D9-1D3C775BA435}</ProjectGuid>
<OutputType>Library</OutputType>
Expand Down Expand Up @@ -68,6 +68,7 @@
<Compile Include="AutoMap\ConventionBuilder.cs" />
<Compile Include="AutoMap\ExpressionBuilder.cs" />
<Compile Include="AutoMap\IAutoMapper.cs" />
<Compile Include="AutoMap\ManyToManyAutoMapper.cs" />
<Compile Include="Cache.cs" />
<Compile Include="Cfg\PersistenceConfiguration.cs" />
<Compile Include="Cfg\PostgreSQLConfiguration.cs" />
Expand Down Expand Up @@ -143,4 +144,4 @@
<Target Name="AfterBuild">
</Target>
-->
</Project>
</Project>
15 changes: 12 additions & 3 deletions src/FluentNHibernate/Mapping/ManyToManyPart.cs
@@ -1,3 +1,4 @@
using System;
using System.Reflection;
using System.Xml;

Expand All @@ -17,16 +18,24 @@ public class ManyToManyPart<PARENT, CHILD> : IMappingPart

public ManyToManyPart(PropertyInfo property)
: this(property.Name)
{
}
{
SetDefaultCollectionType(property.PropertyType);
}

public ManyToManyPart(MethodInfo method)
: this(method.Name)
{
_collectionMethod = method;
SetDefaultCollectionType(method.ReturnType);
}

protected ManyToManyPart(string memberName)
private void SetDefaultCollectionType(Type type)
{
if (type.Namespace == "Iesi.Collections.Generic")
AsSet();
}

protected ManyToManyPart(string memberName)
{
access = new AccessStrategyBuilder<ManyToManyPart<PARENT, CHILD>>(this);
_properties.Store("name", memberName);
Expand Down
7 changes: 7 additions & 0 deletions src/FluentNHibernate/Mapping/OneToManyPart.cs
Expand Up @@ -22,14 +22,21 @@ public class OneToManyPart<PARENT, CHILD> : IOneToManyPart, IAccessStrategy<OneT
public OneToManyPart(PropertyInfo property)
: this(property.Name)
{
SetDefaultCollectionType(property.PropertyType);
}

public OneToManyPart(MethodInfo method)
: this(method.Name)
{
_collectionMethod = method;
SetDefaultCollectionType(method.ReturnType);
}

private void SetDefaultCollectionType(Type type)
{
if (type.Namespace == "Iesi.Collections.Generic")
AsSet();
}

protected OneToManyPart(string memberName)
{
Expand Down

0 comments on commit 794be94

Please sign in to comment.