3

I have a small project using PetaPoco to re-implement Membership Provider, Role Provider and Profile Provider of ASP.NET. And each table has two common field: name and lowered_name. And I face an issue when try to insert new record into database using Database.Insert(), the lowered_name field can not be insert.

E.g we have a table called Category

CREATE TABLE `category` (
  `name` varchar(100) NOT NULL,
  `lowered_name` varchar(100) NOT NULL,
  PRIMARY KEY (`lowered_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

And a Category entity:

[TableName("category"), PrimaryKey("lowered_name")]
    public class Category
    {
        [Column("name")]
        public string Name { get; set; }
        [Column("lowered_name")]
        public string LoweredName { get; set; }
    }

I have use PetaPoco to insert a new category like below

var name = Guid.NewGuid().ToString(); var cat = new Category() { Name = name, LoweredName = name.ToLower() };

        var db = new Database("Test");

        db.Insert(cat);

        var retrievecat = db.SingleOrDefault<Category>("where lowered_name like @0", name.ToLower());

        Console.WriteLine(retrievecat.LoweredName);

        Assert.IsTrue(retrievecat != null);

However, this code doesn't work, a new record was create but the lowered_name field of the record is null. When I change the db.Insert(cat) to:

db.Execute("insert into category(name, lowered_name) values (@0, @1)", name, name.ToLower());

Everything is fine.

I finished implement a lot of code for these providers above and they work well with PostGreSQL and SQL Server, and I don't want to re-implement every Insert function of each repository (I create a common Insert function in the AbstractRepository class).

Do you have any idea?


SchoTime has helped me to fixed the problem if lowered_name is a primary key. However, in my real app, name and lowered_name are not primary key.

I use an abstract class:

public abstract class AbstractEntity
    {
        #region Fields
        private string _name;
        #endregion Fields

        #region Properties
        [PetaPoco.Column(Name = "id")]
        public long Id { get; set; }

        [Required]
        [PetaPoco.Column(Name = "name")]
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                LoweredName = value.ToLower();
            }
        }

        [Required]
        [PetaPoco.Column(Name = "lowered_name")]
        public string LoweredName { get; set; }
        [PetaPoco.Column(Name = "description")]
        public string Description { get; set; }

        #endregion Properties

        #region Initialization
        public AbstractEntity()
        {
        }
        public AbstractEntity(string name)
        {
            Name = name;
        }
        #endregion Initialization
    }

And the User entity:

[PetaPoco.TableName("vietspring_security_user"), PetaPoco.PrimaryKey("id")]
    public class User:AbstractEntity
    {
        #region Private Variables
        private string _email;
        #endregion

        #region Constructors
        public User():base()
        {
            InitMembers();
        }
        public User(int id)
        {
            Id = id;
            InitMembers();
        }
        public User(string name): base(name)
        {
            Name = name;
            InitMembers();
        }
        #endregion


        #region Properties


        [PetaPoco.Column("password")]
        public virtual string Password { get; set; }
        [PetaPoco.Column("password_format")]
        public virtual int PasswordFormat { get; set; }
        [PetaPoco.Column("password_salt")]
        public virtual string PasswordSalt { get; set; }
        [PetaPoco.Column("email")]
        public virtual string Email
        {
            get
            {
                return _email;
            }
            set
            {
                _email = value;
                LoweredEmail = value.ToLower();
            }
        }
        [PetaPoco.Column("lowered_email")]
        public virtual string LoweredEmail { get; set; }
        [PetaPoco.Column("password_question")]
        public virtual string PasswordQuestion { get; set; }
        [PetaPoco.Column("password_answer")]
        public virtual string PasswordAnswer { get; set; }
        [PetaPoco.Column("comments")]
        public virtual string Comments { get; set; }
        [PetaPoco.Column("is_approved")]
        public virtual bool IsApproved { get; set; }
        [PetaPoco.Column("is_locked_out")]
        public virtual bool IsLockedOut { get; set; }
        [PetaPoco.Column("creation_date")]
        public virtual DateTime CreationDate { get; set; }
        [PetaPoco.Column("last_activity_date")]
        public virtual DateTime LastActivityDate { get; set; }
        [PetaPoco.Column("last_login_date")]
        public virtual DateTime LastLoginDate { get; set; }
        [PetaPoco.Column("last_locked_out_date")]
        public virtual DateTime LastLockedOutDate { get; set; }
        [PetaPoco.Column("last_password_change_date")]
        public virtual DateTime LastPasswordChangeDate { get; set; }
        [PetaPoco.Column("failed_password_attempt_count")]
        public virtual int FailedPasswordAttemptCount { get; set; }
        [PetaPoco.Column("failed_password_attempt_window_start")]
        public virtual DateTime FailedPasswordAttemptWindowStart { get; set; }
        [PetaPoco.Column("failed_password_answer_attempt_count")]
        public virtual int FailedPasswordAnswerAttemptCount { get; set; }
        [PetaPoco.Column("failed_password_answer_attempt_window_start")]
        public virtual DateTime FailedPasswordAnswerAttemptWindowStart { get; set; }
        [PetaPoco.ResultColumn]
        public virtual IList<Application> Applications { get; set; }
        #endregion

        ...
    }

And in MembershipProvider, I call these below methods to create new User:

var userId = Convert.ToInt64(_userRepository.Insert(user));
                    _userRepository.AddApplication(app.Id, userId);
                    status = MembershipCreateStatus.Success;

I'm success in save user but name and lowered_name fields are null. How about this situation?

tumivn
  • 53
  • 1
  • 6
  • What is the sql that is produced when the insert happens? Hook into the on `OnExecutedCommand` method on the `Database` object and print out the `LastCommand` property. – Schotime Jun 10 '12 at 10:52

1 Answers1

5

Because you have a primary key of lowered_name and it doesn't appear to be an auto increment column then you must set autoIncrement false as below.

[PrimaryKey("lowered_name", autoIncrement=false)]

AutoIncrement is true by default.

Schotime
  • 15,707
  • 10
  • 46
  • 75
  • Thank you very much, It works in the above example, however, in my real application, the lowered_name and name fields are not primary key. They are normal fields. I will edit the question so you can help me more. Thanks again! – tumivn Jun 10 '12 at 09:24
  • Im considering jumping to Peta-poco, but this issue is a reall kicker... any word on a solution? – Simon Oct 10 '12 at 11:58
  • I'm now not sure what the problem is? Can you create an issue on https://github.com/schotime/NPoco/issues Thanks. – Schotime Oct 13 '12 at 23:20