How to avoid Null Insert on Required TPH Columns for types that don't implement the required column - entity-framework

I've get a set of Class that utilize TPH inheritance.
So all of the types are in the "Documents" table.
Some document types have unique fields. If a sub document type has a non nullable field, the other types are getting an error when creating the entity, because EF tries to insert NULL into that column in the DB - because the subtype doesn't know about that column.
I have tried using defaultValue in a migration to default it to zero, but get the same result.
Is it possible to have a non nullable field in an inherited type, where the base type does not have that field at all?
Or will that always result in the "cannot insert the value Null in column x" error?
In this case the column is an enum.
Should I make it nullable and force it to be required some other way?

Related

Is it bad for columns in composite keys to have mismatching types?

Problem:
I'd like to make a composite primary key from columns id and user_id for a postgres database table. Column user_id is a foreign key with an integer type, whereas id is a string. Will this cause a conflict because the types are different?
Edit: Also, are there combinations of types that would cause problems?
Context:
I obviously should match the type of the User.id field for its foreign key. And, the id for my table will be derived from a uuid to prevent data leaks. So I would prefer not to change the types of either field I want in this table.
Research:
I am using sqlalchemy. Their documentation mentions how to create a composite primary key, but it doesn't discuss dealing with different types for each column.
No, this won't be a problem.
Your question seems to indicate that you think, the values of the indexed columns are somehow concatenated and then stored in the index as a single value. This is not the case. Each column value is stored independently but together. Similar to the way the column values are stored in the actual table.

Upgrading enum type column to varchar in postgresql

I have an enum type column in my table . I have now decided to make it a varchar type and put some constraint.
Q1) Which is a good practice : to have enums or to put constarint on the column.
Q2) How to change my enum type column to varchar. Just opposite to this question question .
I tried using this:
ALTER TABLE tablename ALTER COLUMN columnname TYPE VARCHAR
But this gives me the error : No operator matches the given name and argument type(s). You might need to add explicit type casts.
This is the table definition:
CREATE TABLE tablename (
id1 TEXT NOT NULL,
id2 VARCHAR(100) NOT NULL,
enum_field table_enum,
modified_on TIMESTAMP NOT NULL DEFAULT NOW(),
modified_by VARCHAR(100),
PRIMARY key (id1, id2)
);
For future reference: I had the similar issue with altering enum type and I got the same error message as the one above. In my case, the issue was caused by having a partial index that referenced a column that was using that enum type.
As for best practice, it is best if you define a separate table of possible values, and make your column a foreign key to this table. This has the following benefits:
The new table can not only have the specific key as a type, it can have additional columns with details such as a friendly name, meaning of the type or more information
Changing the possible values is a matter of manipulating data rows (INSERT,UPDATE or DELETE) which is more accessible and manageable than changing constraints or enum values.

EF TPH - can I use a boolean column as a discriminator?

I am using Entity Framework.
Is it possible to use a boolean column as a discriminator column in Table Per Hierarchy (TPH) scenario?
I do not control the database.
Yes, it is possible. Assume you have discriminator column named EntityType:
modelBuilder.Entity<ParentEntity>()
.Map<DerivedA>(m => m.Requires("EntityType").HasValue(true))
.Map<DerivedB>(m => m.Requires("EntityType").HasValue(false));
That requires discriminator column to be of type (bit, null)

Entity Framework on primary key and is null

I need to map some external database, I can't modify the schema. But the tables don't have primary key but rather columns like Client_ID, Calendar_ID but they are not null and entity can map them, much worse is if these columns in few tables can be null, then Entity Framework throws an error that it can't be mapped.
My question is: can I somehow disable entity tracking and map these tables without primary key and with columns as null?
Or can I use code-first approach, does it let me to create and map class with no primary key and all columns as is null?
Entity Framework must have a key field in order to work. It doesn't have to be a true primary key in the database but it needs to be unique. If you have tables that have a nullable field and no true primary key and you can't modify the database then maybe Entity Framework isn't the best fit for this project. It might work if you never try and load the entities with the null values, but it will throw errors when you do (as you have noticed).

PostgreSQL: changing a column of enum type

This is the definition of the enumerated type:
CREATE TYPE khstate AS ENUM ('none', 'form', 'test', 'finished');
Now, in a database table I have a row with columns 'id' (type SERIAL) and 'state' (type khstate). The value of the 'id' column is 100004, and the value of the 'state' column is 'none'. How do I change it to, say, 'form'? The table definition is as follows.
CREATE TABLE IF NOT EXISTS khs (
id SERIAL UNIQUE,
state khstate DEFAULT 'none',
PRIMARY KEY (id)
);
I have tried queries such as
UPDATE tablename SET state = 'form' WHERE id = 100004;
ERROR: invalid input value for enum khstate: "form"
UPDATE tablename SET state = 'form'::khstate WHERE id = 100004;
ERROR: invalid input value for enum khstate: "form"
but without success. I am using the latest BitNami LAPPstack, so the version of PostgreSQL is 9.1.1.
I havent added any RULE or TRIGGER constraints, nor have I used transactions explicitly.
I tried to google for a solution, but all I could find were questions how to change the enum type itself, rather than the value of a column.
The error message indicates that 'form' is not a registered value for your enum type khstate.
I also notice that in your question you create a table named khs, but the UPDATE example uses tablename instead.
There may be a mixup of tables, schemas or databases. Diagnose your problem by running this query in the same session that gives you the error message:
SELECT enum_range(NULL::khstate)
Do you see form in the array of values? I expect, you don't.
More about enum support functions in the manual.