Вставка записей в postgres с использованием NHibernate 3.2 (loquacious) и отображений bycode - PullRequest
0 голосов
/ 25 января 2012

Я работаю над очень простой задачей NHibernate 3.2, вставляя записи в существующие таблицы Postgres. Я использую очень простой объект, чтобы они имели смысл для этого вопроса.

Таблицы postgres:

CREATE TABLE cat
(
  id serial NOT NULL,
  "name" character varying(50) NOT NULL,
  sex_id integer NOT NULL,
  CONSTRAINT cat_pkey PRIMARY KEY (id),
  CONSTRAINT cat_sex_id_fkey FOREIGN KEY (sex_id)
      REFERENCES sex (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
  OIDS=FALSE
);

CREATE TABLE sex
(
  id serial NOT NULL,
  "name" character varying(10) NOT NULL,
  CONSTRAINT sex_pkey PRIMARY KEY (id),
  CONSTRAINT sex_name_key UNIQUE (name)
)
WITH (
  OIDS=FALSE
);

Мои классы отображения следующие:

public class CatMap : ClassMapping<Cat>
    {
        public CatMap()
        {
            Table("cat");
            Id(x => x.Id, map =>
            {
                map.Column("id");
                map.Generator(NHibernate.Mapping.ByCode.Generators.Native);
            });
            Property(x => x.Name, map =>
            {
                map.Column("name");
                map.Length(50);
                map.NotNullable(true);
            });

            ManyToOne(x => x.Sex, map =>
            {
                map.Column("Sex");
                map.Unique(true);
                map.ForeignKey("cat_sex_id_fkey");
            });
        }
    }

public class SexMap : ClassMapping<Sex>
    {
        public SexMap()
        {
            Table("sex");
            Id(x => x.Id, map =>
                {
                    map.Column("id");
                    map.Generator(Generators.Native);
                });
            Property(x => x.Name, map => 
                {
                    map.Column("name");
                    map.Unique(true);
                    map.Length(10);
                    map.NotNullable(true);
                });
        }
    }

Мои классы данных следующие:

public class Sex
{
    public Sex() 
    {
    }
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
}

public class Cat
{
    public Cat() 
    {
    }
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual Sex Sex { get; set; }
}

Наконец, класс, содержащий код, где я на самом деле пытаюсь использовать все вышеперечисленное.

public class Class1
    {
        public string DoSomething()
        {
            var sessionFactory = CreateSessionFactory();

            using (var session = sessionFactory.OpenSession())
            {
                using (var transaction = session.BeginTransaction())
                {
                    Postgres.Tables.Sex sex1 = new Postgres.Tables.Sex() { Name = "Male" };
                    Postgres.Tables.Sex sex2 = new Postgres.Tables.Sex() { Name = "Female" };

                    Postgres.Tables.Cat cat1 = new Postgres.Tables.Cat() { Name = "Cat1" };
                    cat1.Sex = sex1;
                    Postgres.Tables.Cat cat2 = new Postgres.Tables.Cat() { Name = "Cat2" };
                    cat2.Sex = sex2;

                    session.SaveOrUpdate(sex1);
                    session.SaveOrUpdate(sex2);
                    session.SaveOrUpdate(cat1);
                    session.SaveOrUpdate(cat2);

                    transaction.Commit();
                }
            }

            return "I created the cats.";
        }

        private static ISessionFactory CreateSessionFactory()
        {
            NHibernate.Mapping.ByCode.ModelMapper modelMapper = new NHibernate.Mapping.ByCode.ModelMapper();
            System.Type[] mappingTypes = typeof(Postgres.Tables.Mappings.CatMap).Assembly.GetExportedTypes().Where(t => t.Name.EndsWith("Map")).ToArray();
            modelMapper.AddMappings(mappingTypes);
            Configuration cfg = new Configuration();
            cfg.Proxy(p => p.ProxyFactoryFactory<NHibernate.Bytecode.DefaultProxyFactoryFactory>());
            cfg.DataBaseIntegration(d =>
                {
                    d.ConnectionString = "server=192.168.1.126;Port=5432;Database=simple;User Id=postgres;Password=postgres;";
                    d.Dialect<NHibernate.Dialect.PostgreSQL82Dialect>();
                });
            cfg.AddMapping(modelMapper.CompileMappingForAllExplicitlyAddedEntities());
            return cfg.BuildSessionFactory();
        }
    }

Я получаю исключение GenericADOException в "session.SaveOrUpdate (cat1)" с сообщением "не удалось вставить: [DAL.Postgres.Tables.Cat] [SQL: INSERT INTO cat (name, Sex) VALUES (?,?) ; выберите lastval ()] ". InnerException - "{" ОШИБКА: 42703: столбец \ "пол \" отношения \ "кошка \" не существует "}".

Я немного озадачен тем, как правильно назначить "sex1" для "cat1" и "sex2" для "cat2", так что первым будет мужчина, а вторым - женщина.

Спасибо за любой вклад.

1 Ответ

1 голос
/ 25 января 2012

m.Column («Пол») в качестве имени обозначает название столбца, а не имя свойства, как вы указали. Поэтому вы должны написать m.Column ("sex_id"). map.ForeignKey ("cat_sex_id_fkey") используется NH как имя FK, когда NH создает схему БД из вашего отображения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...