nhibernate / fluent-nhibernate Goto Github PK
View Code? Open in Web Editor NEWFluent NHibernate!
License: BSD 3-Clause "New" or "Revised" License
Fluent NHibernate!
License: BSD 3-Clause "New" or "Revised" License
Currently the MemberAccessResolver
isn't used for component properties mapped with a ComponentMap
. Additionally there is no way to use the Access
object which is returned from the MemberAccessResolver
to specify the access strategy in a convention (the access strategy can only be specified with the fluent methods).
Either one of this two ways should be possible, preferably the first (MemberAccessResolver
).
The mapping methods for collections are a mess. We should refine them greatly. This will probably mean a HasMany
call for each of bag
, set
, list
, and map
.
We still don't support many-to-any
When wanting a good unique filename for the .hbm.xml's, the Assembly.FullName will be unique, but it may exceed Windows 260 character path limits.
e.g. I had a class with two generic parameters that had the FullName
GapFillVerification.Models.Audits.ThingAudit`2[[GapFillVerification.Models.Record, gapfill-verification-models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[GapFillVerification.Models.Audits.LockAction, gapfill-verification-models, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
That's 298 characters on it's own, ignoring any path before it.
Exception trace was:
[exec] The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
[exec] at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength)
[exec] at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
[exec] at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, String msgPath, Boolean bFromProxy)
[exec] at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
[exec] at System.Xml.XmlTextWriter..ctor(String filename, Encoding encoding)
[exec] at FluentNHibernate.PersistenceModel.<>c__DisplayClass5.<WriteMappingsTo>b__4(HibernateMapping mapping) in C:\projects\jagregory-fluent-nhibernate-c24de5a\src\FluentNHibernate\PersistenceModel.cs:line 246
[exec] at FluentNHibernate.PersistenceModel.WriteMappingsTo(Func`2 writerBuilder, Boolean shouldDispose) in C:\projects\jagregory-fluent-nhibernate-c24de5a\src\FluentNHibernate\PersistenceModel.cs:line 269
[exec] at FluentNHibernate.PersistenceModel.WriteMappingsTo(String folder) in C:\projects\jagregory-fluent-nhibernate-c24de5a\src\FluentNHibernate\PersistenceModel.cs:line 242
[exec] at FluentNHibernate.Cfg.FluentMappingsContainer.Apply(PersistenceModel model) in C:\projects\jagregory-fluent-nhibernate-c24de5a\src\FluentNHibernate\Cfg\FluentMappingsContainer.cs:line 131
[exec] at FluentNHibernate.Cfg.MappingConfiguration.Apply(Configuration cfg) in C:\projects\jagregory-fluent-nhibernate-c24de5a\src\FluentNHibernate\Cfg\MappingConfiguration.cs:line 84
[exec] at FluentNHibernate.Cfg.FluentConfiguration.BuildConfiguration() in C:\projects\jagregory-fluent-nhibernate-c24de5a\src\FluentNHibernate\Cfg\FluentConfiguration.cs:line 252
http://msdn.microsoft.com/en-us/library/Aa365247#maxpath indicates the use of the "?" prefix might help, but then XmlTextWriter starts throwing exceptions about "invalid characters"...
Is Fluent Hardcoded to use the Castle ProxyFactoryFactory?
See: https://groups.google.com/forum/#!topic/fluent-nhibernate/lf2qctfrFzg/discussion
Because the collection is effectively both sides of the relationship, the validation visitor thinks that inverse is set on both sides and throws a validation exception. Bad!
There does not currently (in v1.0 RTM) seem to be a way to choose which field can have a clustered index created.
I believe that previously, before the rewrite, it was possible to set this. Now the clustered index always appears to be set on the first column of the primary key.
I suggest modifying either IClassInstance or IPropertyInstance to support this functionality.
Especially when using Guids for primary keys, it useful to cluster on something other than that key.
HasMany doesn't work well with collections of interfaces (especially when using Reveal)
public class Episode
{
private IList<IContributor> contributors = new List<IContributor>();
}
public static OneToManyPart<T> ChildType<T>(this OneToManyPart<T> part, Type type)
{
part.GetType()
.GetField("valueType", BindingFlags.Instance | BindingFlags.NonPublic)
.SetValue(part, type);
part.GetType()
.GetField("isTernary", BindingFlags.Instance | BindingFlags.NonPublic)
.SetValue(part, true);
return part;
}
If you inherit from PersistenceModel, the AddMappingsFromThisAssembly doesn't work because it (incorrectly) assumes the calling assembly is in FluentNHibernate.dll.
See: https://groups.google.com/forum/#!topic/fluent-nhibernate/-MDmyisPt_E/discussion
Patch from Robert, not sure why this never got applied. Will review post-1.1.
public class Indexes : FluentIndexBase
{
public Indexes(Configuration configuration)
: base(configuration)
{
AddDialectScope("NHibernate.Dialect.MsSql2005Dialect");
ClusteredIndex<Person>().OnPrimaryKey();
UniqueNonClusteredIndex<Person>().OnProperty(x => x.SSN);
ClusteredIndex<SuperClass>().OnProperty(x => x.Person);
UniqueNonClusteredIndex<SuperClass>().OnProperty(x => x.SomeProperty);
NonClusteredIndex<SuperClass>().OnDiscriminator();
}
}
Merge the Fluent Interface and AutoMappings into one awesome mapping.
What I envision is inspired by StructureMap. Something like the PersistenceModel is equatable to the Repository in StructureMap, where you supply it with mappings (analogous to types). Mappings can be supplied either as instances (or by type) or they can be automapped (analogous to Scanning).
public class MyPersistenceModel : PersistenceModel
{
protected override void Initialise()
{
ForType<Person>
.UseMapping<PersonMap>();
ForTypes
.InNamespace("My.Entities")
.UseMappingsInNamespace("My.Mappings");
ForTypes
.InNamespace("My.SimpleEntities")
.AutoMap();
ForType<Product>
.AutoMap();
}
}
public class PersonMap : ClassMap<Person>
{
protected override Initialise()
{
DiscoverDefaults();
Map(x => x.Name)
.ColumnName("PersonName");
}
}
This ticket should be separated closer to the time of development!
It seems that CheckList enforces ordering on the lists that it checks. I have a many-to-many relationship between Users and Roles as follows:
public UserMap()
{
Id(x => x.Id);
Map(x => x.UserName);
Map(x => x.Email);
HasManyToMany(x => x.Roles)
.Access.CamelCaseField()
.Inverse();
}
public RoleMap()
{
Id(x => x.Id);
Map(x => x.Name);
HasManyToMany(x => x.Users)
.Access.CamelCaseField();
}
My testing is as follows:
/* Create test Users list */
new PersistenceSpecification<Role>(session)
.CheckProperty(u => u.Name)
.CheckList(u => u.Users, users, (role, user) => role.AddUser(user))
.VerifyTheMappings();
Sometimes this fails and sometimes it passes. From some debugging, it seems that it is retrieving the Users in a different order than which they were added. I imagine it because the generated Guid (using Guid.Comb) is altering the order on the database query. (I think it is because the guid is not sequential on the association table.) So basically, even though the list contains the same elements, since they are in a different order, fails the test because the source appears to compare elements by index position. So my question is, should I be enforcing an order on my queries or should CheckList not assume ordering on the list?
I noticed that ToManyBase.Key() disappeared from the trunk. Fiddling with git, I was unable to figure out what happened to it, but then again, my git skills aren't that sharp. I suspect the change wasn't on purpose, though...
I got this issue , it only occured when I run debug, when I run tests without debug it can find it in GAC.
I'd like to map a list of an interface This is my object:
public class Foo
{
public virtual IList<IBar> Bars { get; protected set; }
}
I have several implementations of IBar in my domain model. How do I specify which IBar implementation Foo is using with Fluent NHibernate? I'm using auto mapping and would love if there was a solution with overrides.
I feel like there's a missing Class() method somewhere, but I don't know how to map this with NHibernate, so I'm not sure what I want to do is even possible.
We should piggy-back on NHibernate's logging facilities and use it to write out our own diagnostic logging.
Dear FluentNHibernate developers,
I recently had and issue with Fluent, which involved two one-to-many relationships between the same two entities. (the details are on SO.)
I always had ForeignKey.EndsWith("Id") within my convention collection, because I thought it was a very elegant way of expressing what I want.
The problem is, that when I have multiple many-to-one relationship between the same entites, Fluent can't figure out which property maps to which collection, but this is the least of the problems.
I set up a HasManyConvention and a ReferenceConvention (attached), in which I provided some logics about how to do it.
This is where things got messy: with ForeignKey.EndsWith, it actually created a third column for one of the entities, and the relationships didn't work. So in the end, I tried putting the naming into the HasMany and Reference conventions, and it just worked. I honestly don't know if this is by design or just an error, but for other people experiencing the same issue, it would be helpful if you wrote it in the wiki that it isn't working well in such scenarios.
Yours sincerely,
Timur Kristóf
The automapper should ignore base classes by default that fall outside of the where criteria.
Currently we have to deal with multiple PersistenceModels, this is a bit weird. Refactor towards a single PersistenceModel, unifying all conventions and automapping.
Rewrite the automapper to allow substitutable behaviour.
The automapper currently uses a bunch of "setup" funcs that define how it behaves; however, this isn't very flexible as it's only capable of working in the set few ways we allow it to.
Rewrite the automapping internals to use a strategy that can be passed in by the user (or a default implementation provided by us).
AutoMap.AssemblyOf<X>()
.WithStrategy(new MyCustomAutomappingStrategy());
With the advent of #13, the AutoMap/AutoPersistenceModel should be depreciated in favour of creating your own PersistenceModel which can be used to specify any automappings along side your other mappings.
The conventions are currently supplied at the individual mapping types level (FluentMappings and AutoMappings) within the Fluently.Configure API. I'd prefer it if you could specify conventions across the board more easily.
We should maintain this stuff independently of Fluent NHibernate core, as it's orthogonal to the main codebase. This could potentially be ported to EF if there's interest too.
We should warn the user about inverse being on both sides of a relationship. Make sure to accomodate self-referential relationships.
When using Fluent 1.0.0.363, I had the following Convention applied, which worked fine. Upgrading to anything newer and I get this exception:
FluentNHibernate.Cfg.FluentConfigurationException : An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.
----> NHibernate.MappingException : Could not compile the mapping document: (XmlDocument)
----> NHibernate.MappingException : Could not determine type for: MyNS.Price, MyNS for columns: NHibernate.Mapping.Column(PricePerUnit)
I can't stay on .363 through, because the ComponentMap and SubClassMap don't play nice together on that version. Fluent is finding all of my conventions as debugging I see it calling Accept for OTHER properties, but it doesn't ever call it for the Price struct. I have this same problem where i have a UserTypeConvention as well. It works fine in 363, but doesn't get applied in later versions.
Any ideas? Here's the convention:
public sealed class PriceConvention : IPropertyConvention, IPropertyConventionAcceptance
{
#region IConventionAcceptance<IPropertyInspector> Members
public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
{
criteria.Expect(x => x.Property.PropertyType == typeof(Price));
}
#endregion
#region IConvention<IPropertyInspector,IPropertyInstance> Members
public void Apply(IPropertyInstance instance)
{
instance.CustomType<decimal>();
instance.CustomSqlType("money");
}
#endregion
}
Allow conventions to create new mappings; should be able to map new properties, create components, collections, etc in a conventional manner.
ComponentMap currently only works for normal components, it would be very useful to use it with composite-element collections too.
If the user defined a mapping as follows:
HasMany(x => x.Children)
.KeyColumns.Add("one") .Unique() .KeyColumns.Add("two");
Then the behaviour is to have two column mappings created, each with the unique set to true. This is somewhat counter-intuitive. It would be better to handle multiple columns with something like
.KeyColumns.Add("name", c => { optional column mapping });
Yesterday I grab last available sources of FNH to make it possible to use it with NH 3.2.0.4GA. But after update to new version (1.3) I start getting the following error:
FluentNHibernate.Cfg.FluentConfigurationException: An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.
This happens then I map ICompositeUserType:
C# Map(m => m.Amount).CustomType<MoneyCompositeType>();
After call CustomType method, returned PropertyPart object contains correct number of columns, but then FNH visitor visit this property during NH mapping generation it Columns collection contains only one column named as Property.
May be this information will be useful: this property located in class that mapped as Component.
I think this is the bug. How can I fix it?
Mapping parts have a method that looks something like this:
public ClassMapping GetClassMapping()
{
mapping.Name = typeof(T).AssemblyQualifiedName;
foreach (var property in properties)
mapping.AddProperty(property.GetPropertyMapping());
....
}
Ideally, the underlying mapping model would always be "up to date" rather than requiring this explicit build step.
See: https://groups.google.com/forum/#!topic/fluent-nhibernate/gs-wnmjiZ-M/discussion
Couldn't reproduce, but could be something to do with ExportTo
being called first.
"Regression" from master functionality.
Support dictionaries in the automapper. Should default to Map I guess, unless we can work out a way to support dynamic-components.
SubclassMap doesn't work with automapping.
Conventions are currently applied to the final model, with some hacks to stop them from overwriting any of the user's fluent-interface defined mappings; this needs to be changed so conventions are applied before the user's stuff.
Should be able to filter the assembly that gets scanned for Fluent mappings. Sometimes not all the ClassMaps are needed by the current SessionFactory.
Fluently.Configure is a hacky mess and not very intuitive. It should be deprecated in favour of a simpler extension method approach. Something like this:
new Configuration() // Regular NHibernate config
.ApplyMappingsFrom<MyPersistenceModel>() // Our extension method
.BuildSessionFactory(); // Back to NHibernate again
Hey Guys,
I opened this topic within stackoverflow already, but until now there is no answer. Maybe you can have a look:
http://stackoverflow.com/questions/6827154/mapping-compositeid-keyreference-on-interface
Thanks.
The table name that's generated by the automapper for element collections is the property name of the collection. If different entities use the same collection name then there'll be conflicts. We should prefix the table name with the Entity name or something.
The v1.x branch is the primary codebase, and master has become out of date and contains breaking changes. It'd be better if we just ditch the current master all together and continue work from the v1.x branch.
This should just mean doing: git merge -Xtheirs v1.x
from the master
branch.
Diagnostics were started in 1.2 but never really completed or tested. They should be refined and made more useful for the next release.
Automapping overrides don't seem to accept ImportType calls.
Needs a significant refactor of the automapping code to get this to work
Need to put some thought into how to support multiple databases. Some people switch between oracle and sql server (or sqlite) which have different defaults for id generators and naming conventions. We should be able to determine what each DB likes and give it that, instead of making the user duplicate stuff.
.UseOverridesFromAssemblyOf<>()
and .UseOverridesFromAssembly()
when used within an inherited PersistenceModel
cause an "Object reference not set to an instance of an object" exception at line 366 of FluentNhibernate/automapping/AutoPersistenceModel.cs.
The attempt to retrieve a reference to the "OverrideHelper" method via this.GetType() returns null:
var overrideInstance = Activator.CreateInstance(overrideType);
GetType()
.GetMethod("OverrideHelper", BindingFlags.NonPublic | BindingFlags.Instance)
.MakeGenericMethod(entityType)
.Invoke(this, new [] {x, overrideInstance});
private void OverrideHelper<T>(AutoMapping<T> x, IAutoMappingOverride<T> mappingOverride)
{
mappingOverride.Override(x);
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.