views:

92

answers:

3

I'm trying to map myexisting database by Fluent NHibernate I get error:

The element 'class' in namespace 'urn:nhibernate-mapping-2.2' has invalid child element 'many-to-one' in namespace 'urn:nhibernate-mapping-2.2'. List of possible elements expected: 'meta, subselect, cache, synchronize, comment, tuplizer, id, composite-id' in namespace 'urn:nhibernate-mapping-2.2'."}

I'm newbie in Fluent and I don't know how to fix it ? (maybe it is because id is string ?)

Here is my model class:

namespace Server.Model
{
    public partial class User
    {
        string _name;

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        string _email;

        public string Email
        {
            get { return _email; }
            set { _email = value; }
        }
        TypeOfUser _typeOfUser;

        public TypeOfUser TypeOfUser
        {
            get { return _typeOfUser; }
            set { _typeOfUser = value; }
        }
        string _idUser;

        public string IdUser
        {
            get { return _idUser; }
            set { _idUser = value; }
        }

        public string Password { get; set; }

        public static void AddUserTest()
        {
            var sessionFactory = BuildSessionFactory();

            using (ISession session = sessionFactory.OpenSession())
            {

                using (ITransaction transaction = session.BeginTransaction())
                {

                    session.Save(new User()
                                     {
                                         _idUser = "adapol",
                                         _name = "Adam Mickiewicz",
                                         _email = "[email protected]",
                                         _typeOfUser = Model.TypeOfUser.NormalUser
                                     });
                }
            }
        }

        private static ISessionFactory BuildSessionFactory()
        {
            AutoPersistenceModel model = CreateMappings();

            return Fluently.Configure().Database(MsSqlConfiguration.MsSql2005
  .ConnectionString(c => c.FromConnectionStringWithKey("gwd"))).Mappings(m => m.AutoMappings.Add(model))
    .ExposeConfiguration((Configuration config) => new SchemaExport(config).Create(false, true)).BuildSessionFactory();

        }

        private static AutoPersistenceModel CreateMappings()
        {
            return AutoMap
                .Assembly(System.Reflection.Assembly.GetCallingAssembly())
                .Where(t => t.Namespace == "Server.Mappings");
        }


    }
}

I have only one classMap

namespace Server.Mappings
{
    public class UserMap : ClassMap<User>
    {
        public UserMap()
        {
            Table("Users");

            Id(x => x.IdUser,"IdUser");
            Map(x => x.Email);
            Map(x => x.Name);
            Map(x => x.Password);
            Map(x => x.TypeOfUser,"Type");
        }
    }
}

This is script to create my table( it already exists):

USE [GWD]
GO
/****** Object:  Table [dbo].[Users]    Script Date: 09/02/2010 23:08:02 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Users](
    [IDuser] [nvarchar](50) NOT NULL,
    [Type] [int] NOT NULL,
    [Name] [nvarchar](max) NOT NULL,
    [Email] [nvarchar](50) NOT NULL,
    [Password] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED 
(
    [IDuser] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
A: 

My guess is that you are trying to use AutoMapping but you are pointing the auto-mapper at your mapping namespace not your model. This results in FNH trying to automap your actual mapping classes. You could point AutoMap at your model namespace, but looking at your code you may run into more difficulties. It's probably better at this stage to use the normal, non-auto mapper.

cbp
A: 

I'm guessing you're running an out-of-date version of Fluent NHibernate; if you were running 1.1, you would get a more helpful exception. 90% of the time you (used to) get that exception when your class doesn't have an Id mapped.

I'm fairly sure the automapper isn't finding your Id properties. First, you're getting that exception; second, your ClassMap shows you're using a property named IdUser as the Id in that entity; third, the automapper is configured by default to search for properties called Id only.

I suggest you read the automapping wiki page, as it covers all these things.

James Gregory
+1  A: 

Instead of relying on automappings:

private static ISessionFactory BuildSessionFactory()
        {
            AutoPersistenceModel model = CreateMappings();

            return Fluently.Configure().Database(MsSqlConfiguration.MsSql2005
  .ConnectionString(c => c.FromConnectionStringWithKey("gwd"))).Mappings(m => m.AutoMappings.Add(model))
    .ExposeConfiguration((Configuration config) => new SchemaExport(config).Create(false, true)).BuildSessionFactory();

        }

Try this:

private static ISessionFactory BuildSessionFactory()
{
    return Fluently
        .Configure()
        .Database(
            MsSqlConfiguration
                .MsSql2005
                .ConnectionString(c => c.FromConnectionStringWithKey("gwd"))
         )
         .Mappings(m => m.FluentMappings.AddFromAssemblyOf<UserMap>())
         .ExposeConfiguration(config => new SchemaExport(config).Create(false, true))
         .BuildSessionFactory();
}

Also you might need to make the User properties virtual.


And here's a full working example using SQLite that I've put to illustrate sample configuration:

public class User
{
    public virtual string IdUser { get; set; }
    public virtual string Name { get; set; }
    public virtual string Email { get; set; }
    public virtual string Password { get; set; }
}

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        Table("Users");
        Id(x => x.IdUser);
        Map(x => x.Email);
        Map(x => x.Name);
        Map(x => x.Password);
    }
}


class Program
{
    static void Main(string[] args)
    {
        if (File.Exists("data.db3"))
        {
            File.Delete("data.db3");
        }

        using (var factory = CreateSessionFactory())
        {
            using (var connection = factory.OpenSession().Connection)
            {
                ExecuteQuery("create table Users(IdUser string primary key, Name string, Email string, Password string)", connection);
            }

            using (var session = factory.OpenSession())
            using (var tx = session.BeginTransaction())
            {
                session.Save(new User()
                {
                    IdUser = "adapol",
                    Name = "Adam Mickiewicz",
                    Email = "[email protected]",
                });
                tx.Commit();
            }
        }
    }

    private static ISessionFactory CreateSessionFactory()
    {
        return Fluently.Configure()
            .Database(
                SQLiteConfiguration.Standard.UsingFile("data.db3").ShowSql()
            )
            .Mappings(
                m => m.FluentMappings.AddFromAssemblyOf<UserMap>()
            )
            .BuildSessionFactory();
    }

    static void ExecuteQuery(string sql, IDbConnection connection)
    {
        using (var command = connection.CreateCommand())
        {
            command.CommandText = sql;
            command.ExecuteNonQuery();
        }
    }
}
Darin Dimitrov