Firebird - ID not defined as NOT NULL

Dec 1, 2008 at 11:14 AM

Hello:

I use Firebird and have  the next definition :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lephone.Data.Definition;

namespace Test1
{
    public class Person: IDbObject
    {
        [DbKey(IsDbGenerate = false)]
        public int id;
        public string name;
       
    }
}

and in Main

Person p = DynamicObject.NewObject<Person>();
p.id = 1;
p.nombre = "John";
DbEntry.Save(p);

When I execute Save I Get:

unsuccessful metadata update
Column: ID not defined as NOT NULL - cannot be used in PRIMARY KEY constraint definition

this is my app.donfig:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="Lephone.Settings"
     type="Lephone.Util.Setting.NameValueSectionHandler, Lephone.Util"/>
  </configSections>
  <Lephone.Settings>
    <add key="AutoCreateTable" value="true" />
    <add key="DataBase" value="@Firebird : User=SYSDBA;Password=masterkey;Database=c:\ibase\TEST1.FDB;DataSource=localhost;Port=3050;Dialect=3;Charset=NONE;Role=;Connection lifetime=15;Pooling=true;MinPoolSize=0;MaxPoolSize=50;Packet Size=8192;ServerType=0" />
    <add key="DbProviderFactory" value="@SmartDbFactory : FirebirdSql.Data.FirebirdClient, Version=2.0.1.0, Culture=neutral, PublicKeyToken=3750abcc3150b00c" />
  </Lephone.Settings>
</configuration>

 

 

Coordinator
Dec 1, 2008 at 2:22 PM

I suggest to use it like:

namespace Test1
{
    public abstract class Person : LinqObjectModel<Person>
    {
        public abstract string Name { get; set; }
    }
}

and in Main

Person p = Person.New();
p.Name = "John";
p.Save();

Your issue maybe caused by auto create table feature and maybe it doesn't support the ID which is not Db Generated for firebird or something.

Dec 1, 2008 at 4:07 PM
lifeng: 
Can I to use LinqObjectModel<Person> with a custom PK.?
 I'm trying  DBEntry with legacy Firebird DB and need map special PK configurations (column name is not "ID" or I have compsite KEY)

thanks 
Dec 1, 2008 at 9:38 PM
Hi,

finnaly I've discovered the problem for autocreatables with explicit PK  where IsDbGenerate = false

in CreateTableStatementBuilder.cs

in ....

 public SqlStatement ToSqlStatement(DbDialect dd)
        {
            bool isMutiKey = IsMutiKey();
            string keys = "";
            StringBuilder sql = new StringBuilder();
            sql.Append("CREATE TABLE ");
            sql.Append(dd.QuoteForLimitTableName(TableName));
            sql.Append(" (");

            foreach (ColumnInfo ci in _Columns)
            {
                string NullDefine = ci.AllowNull ? dd.NullString : dd.NotNullString;
                sql.Append("\n\t");
                sql.Append(dd.QuoteForColumnName(ci.Key));
                sql.Append(" ");
                if (ci.IsDbGenerate && dd.IdentityTypeString != null)
                {
                    sql.Append(dd.IdentityTypeString);
                }
                else
                {
                    sql.Append(dd.GetTypeName(DataTypeParser.Parse(ci.ValueType), ci.IsUnicode, ci.Length));
                }
                if (ci.IsDbGenerate)
                {
                    sql.Append(" ").Append(dd.IdentityColumnString);
                }
                if (ci.IsKey)
                {
                    if (isMutiKey)
                    {
                        sql.Append(NullDefine);
                        keys += dd.QuoteForColumnName(ci.Key) + ", ";
                    }
                    else if (ci.ValueType == typeof(Guid))
                    {
                        sql.Append(" PRIMARY KEY");
                    }
                    else
                    {
                        if (!dd.IdentityIncludePKString)
                        {

                            // mapner NOTE: ********** must insert this.... <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

                            sql.Append(NullDefine); 

                            // ***************************** <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

                            sql.Append(" PRIMARY KEY");
                        }
                    }
                }
                else
                {
                    sql.Append(NullDefine);
                }
                sql.Append(",");
            }
            if (_Columns.Count != 0)
            {
                if (isMutiKey)
                {
                    sql.Append("\n\tPRIMARY KEY(").Append(keys.Substring(0, keys.Length-2)).Append(")");
                }
                else
                {
                    sql.Length--;
                }
            }
            sql.Append("\n);\n");
            if (HasOneDbGenKey())
            {
                sql.Append(dd.GetCreateSequenceString(TableName));
            }
            // Create Index
            AddCreateIndexStatement(sql, dd);
            return new SqlStatement(CommandType.Text, sql.ToString());
        }

regards
Coordinator
Dec 2, 2008 at 12:42 AM

Thanks for your work.

I will to ensrue this change works for all the databases.

thx.

Coordinator
Dec 3, 2008 at 4:23 AM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.