GithubHelp home page GithubHelp logo

nhibernate / fluent-nhibernate Goto Github PK

View Code? Open in Web Editor NEW
1.7K 132.0 688.0 50 MB

Fluent NHibernate!

License: BSD 3-Clause "New" or "Revised" License

C# 99.83% PowerShell 0.01% JavaScript 0.03% CSS 0.13%
nhibernate fluent-api c-sharp linq orm fluentnhibernate

fluent-nhibernate's People

Contributors

aaronjensen avatar agross avatar andystewart avatar asbjornu avatar ashmind avatar chadmyers avatar chester89 avatar deepsource-autofix[bot] avatar drlongnecker avatar felixg avatar firo222 avatar hazzik avatar hudsonakridge avatar icambron avatar ignition avatar jagregory avatar jeremydmiller avatar jeremyskinner avatar jrgcubano avatar leemhenson avatar maxild avatar mbp avatar notmyself avatar oskarb avatar owerkop avatar paulbatum avatar renovate[bot] avatar ryanhauert avatar tgmayfield avatar tunatoksoz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fluent-nhibernate's Issues

Multiple database support

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.

Create Clustered Index on Column of Choice

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.

How to map a list of an interface to a concrete class

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.

Unable to add overrides when using an inherited PersistenceModel

.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);
    }

Reset master to v1.x

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.

Filter FluentMappings

Should be able to filter the assembly that gets scanned for Fluent mappings. Sometimes not all the ClassMaps are needed by the current SessionFactory.

Clean up handling of multiple columns

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 });

Allow top-level convention specifying

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.

Conventional automappings

Allow conventions to create new mappings; should be able to map new properties, create components, collections, etc in a conventional manner.

  • Is this really the automapping?
  • Should there be a distinction between conventions and automappings? (No?)
  • How do we handle the lack of a generic type? (no equivalent to ClassMap)

HasMany interfaces

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;
}

ToManyBase.Key() gone?

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...

Clean up how conventions are applied to the model

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.

More diagnostics

Diagnostics were started in 1.2 but never really completed or tested. They should be refined and made more useful for the next release.

FNH 1.3: Mapping to the ICompositeUserType broken

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.

  • Database was not configured through Database method.
    ---> NHibernate.MappingException: property mapping has wrong number of columns: CashDepartment.Server.DomainModel.Enities.Service.Rate type: component[RateType,PaymentCondition,FixedAmountData,FixedCostOfArivalData,PercentageData]
    at NHibernate.Mapping.PersistentClass.Validate(IMapping mapping) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Mapping\PersistentClass.cs:line 954
    at NHibernate.Mapping.RootClass.Validate(IMapping mapping) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Mapping\RootClass.cs:line 371
    at NHibernate.Cfg.Configuration.ValidateEntities() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs:line 1030
    at NHibernate.Cfg.Configuration.Validate() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs:line 958
    at NHibernate.Cfg.Configuration.BuildSessionFactory() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Cfg\Configuration.cs:line 1250
    at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory()
    --- End of inner exception stack trace ---
    at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory()

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?

Table name of automapped value collection isn't correct

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.

Remove the explicit mapping model build step

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.

Conventions are not being honored

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
}

PersistenceSpecification CheckList fails on Many-to-Many relationship

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?

Automapping strategies

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());

Merge Fluent Interface and AutoMap

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!

Logging

We should piggy-back on NHibernate's logging facilities and use it to write out our own diagnostic logging.

Assembly FullNames can be too long for NHibernate mapping filenames

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"...

Use the MemberAccessResolver for properties mapped with a CompontentMap

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).

Collection refactoring

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.

Fluent index creation

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();
  }
}

Deprecate Fluently.Configure

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

ForeignKey.EndsWith messes up multiple one-to-many relationships

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.