OData $metadata error - entity-framework

I have a WCF Data Service (5.5) sitting over an EF (5.0) model,
I'm getting the following error when I query $metadata:
"An IEdmModel instance was found that failed validation. The following errors were reported:
InvalidMultiplicityOfDependentEnd : The multiplicity of the dependent end 'QuestionsetMember' is not valid. Because the dependent properties don't represent the dependent end key, the the multiplicity of the dependent end must be '*'."
QuestionsetMember has a composite primary key of 2 columns, each of which is hooked to a primary key of another table, i.e. a foreign key exist from each column of the key to the two tables' primary keys.
I've searched but cannot find any info on "InvalidMultiplicityOfDependentEnd".
Also tried fiddling with the relationships in the EDMX, but changing the End Multiplicity causes errors which won't allow the model to compile.
Any ideas how to get round this (hopefully without changing my schema) ?

This seems to be a very rare error. I did not find anywhere else an explanation of that error. So i did find for me a solution after inspecting every single constraint and every column in both tables. To my great surprise the order of the primary key columns seems to be relevant.
For explanation: I do the database-design within the sql server management studion, and update my model with the entity framework designer.
First Table:
CREATE TABLE Table1
(
Column1 int NOT NULL,
Column2 int NOT NULL,
PRIMARY KEY (Column1,Column2)
)
Second Table:
CREATE TABLE Table2
(
Column1 int NOT NULL,
Column2 int NOT NULL,
PRIMARY KEY (Column1,Column2)
FOREIGN KEY (Column1,Column2) REFERENCES Table1(Column1,Column2)
)
This would work. But it do not work, if you would define the columns of the primary key in the second table in another order:
CREATE TABLE Table2
(
-- Changed order in definition:
Column1 int NOT NULL,
Column2 int NOT NULL,
-- Changed order in PK group:
PRIMARY KEY (Column2,Column1)
-- Leave the FK definition untouched:
FOREIGN KEY (Column1,Column2) REFERENCES Table1(Column1,Column2)
)
I think the order of the column definition has impact on the generated model. And this order could maybe have an impact in the model validation within the IEdmModel class. Who knows...

Related

What is <?>() in postgresql DDL?

I have two trivial tables in postgres 14 schema:
Table 1 rubric_questions:
rubric_version_id : int
rubric_id : int
FK: (rubric_id, rubric_version_id) -> rubric(rubric_id, version_id) /// note it is id THEN version
Table 2 rubrics:
rubric_id : int
rubric_version_id : int
PK: (version_id, rubric_id) /// note it is version THEN id
Obviously it is wrong that order of columns in first table's FK is reverse of second tabel's PK.
However when I use Generate DDL function in DBeaver it returns the following, note the FK definition:
CREATE TABLE eval.rubric_questions (
rubric_version_id int4 NOT NULL,
rubric_id int4 NOT NULL
);
ALTER TABLE eval.rubric_questions ADD CONSTRAINT rubric_questions_fk FOREIGN KEY (rubric_id,rubric_version_id) REFERENCES <?>();
I'm trying to scaffold entity framework code-first, and it chokes on this relationship with:
Could not scaffold the foreign key 'eval.rubric_questions(rubric_version_id,rubric_id)'. A key for 'version_id,rubric_id' was not found in the principal entity type 'Rubric'.
Reversing FK columns fixes the issue.
I understand that I will need to fix the column order, but this issue exists in several places, so I would like to get the scaffold going and then fix these problems as I discover them (I have inherited the schema that I need to use in my new EF-based application).
Question: Is this <?>() syntax documented somewhere, or is it postgresql bug? Is there a work-around without changing the schema?u

How to edit a record that results in a uniqueness violation and echo the change to child tables?

PostgreSQL 11.1
How can "Editing" of a record be transmitted to dependent records?
Summary of my issue:
The master table, disease, needs a unique constraint on the description column. This unique constraint is needed for foreign key ON UPDATE CASCADE to its children tables.
To allow for a temporary violation of the unique constraint, it must be made deferrable. BUT A DEFERABLE CONSTRAINT CAN NOT BE USED IN A FOREIGN KEY.
Here is the situation.
The database has 100+ tables (and keeps on growing).
Most all information has been normalized in that repeating groups of information have been delegated to their own table.
Following normalization, most tables are lists without duplication of records. Duplication of records within a table is not allowed.
All tables have a unique ID assigned to each record (in addition to a unique constraint placed on the record information).
Most tables are dependent on another table. The foreign keys reference the primary key of the table they are dependent on.
Most unique constraints involve a foreign key (which in turn references the primary key of the parent table).
So, assume the following schema:
CREATE TABLE phoenix.disease
(
recid integer NOT NULL DEFAULT nextval('disease_recid_seq'::regclass),
code text COLLATE pg_catalog."default",
description text COLLATE pg_catalog."default" NOT NULL,
CONSTRAINT disease_pkey PRIMARY KEY (recid),
CONSTRAINT disease_code_unique UNIQUE (code)
DEFERRABLE,
CONSTRAINT disease_description_unique UNIQUE (description)
,
CONSTRAINT disease_description_check CHECK (description <> ''::text)
)
CREATE TABLE phoenix.dx
(
recid integer NOT NULL DEFAULT nextval('dx_recid_seq'::regclass),
disease_recid integer NOT NULL,
patient_recid integer NOT NULL,
CONSTRAINT pk_dx_recid PRIMARY KEY (recid),
CONSTRAINT dx_unique UNIQUE (tposted, patient_recid, disease_recid)
,
CONSTRAINT dx_disease_recid_fkey FOREIGN KEY (disease_recid)
REFERENCES phoenix.disease (recid) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE RESTRICT,
CONSTRAINT dx_patients FOREIGN KEY (patient_recid)
REFERENCES phoenix.patients (recid) MATCH SIMPLE
ON UPDATE CASCADE
ON DELETE RESTRICT
)
(Columns not involved in this question have been removed. :) )
There are many other children tables of disease with the same basic dependency on the disease table. Note that the primary key of the disease table is a foreign key to the dx table and that the dx table uses this foreign key in a unique constraint. Also note that the dx table is just one table of a long chain of table references. (That is the dx table also has its primary key referenced by other tables).
The problem: I wish to "edit" the contents of the parent disease record. By "edit", I mean:
change the data in the description column.
if the result of the change causes a duplication in the disease table, then one of the "duplicated" records will need to be deleted.
Herein lies my problem. There are many different tables that use the primary key of the disease table in their own unique constraint. If those tables ALSO have a foreign key reference to the duplicated record (in disease), then cascading the delete to those tables would be appropriate -- i.e., no duplication of records will occur.
However, if the child table does NOT have a reference to the "correct" record in the parent disease table, then simply deleting the record (by cascade) will result in loss of information.
Example:
Disease Table:
record 1: ID = 1 description = "ABC"
record 2: ID = 2 description = "DEF"
Dx Table:
record 5: ID = 5 refers to ID=1 of Disease Table.
Editing of record 1 in Disease table results in description becoming "DEF"
Disease Table:
record 1: ID = 1 "ABC" --> "DEF"
I have tried deferring the primary key of the disease table so as to allow the "correct" ID to be "cascaded" to the child tables. This causes the following errors:
A foreign key can not be dependent on a deferred column. "cannot use a deferrable unique constraint for referenced table "disease"
additionally, the parent table (disease) has no way of knowing ahead of time if its children already have a reference to the "correct" record so allowing deletion, or if the child needs to change its own column data to reflect the new "correct" id.
So, how can I allow a change in the parent table (disease) and notify the child tables to change their column values -- and delete within them selves should a duplicate record arise?
Lastly, I do not know today what future tables I will need. So I cannot "precode" into the parent table who its children are or will be.
Thank you for any help with this.

Is this a good idea to store relations to many different tables in one field? [duplicate]

I have a database which has three tables
Messages - PK = MessageId
Drafts - PK = DraftId
History - FK = RelatedItemId
The History table has a single foreign Key [RelatedItemId] which maps to one of the two Primary keys in Messages and Drafts.
Is there a name for this relationship?
Is it just bad design?
Is there a better way to design this relationship?
Here are the CREATE TABLE statements for this question:
CREATE TABLE [dbo].[History](
[HistoryId] [uniqueidentifier] NOT NULL,
[RelatedItemId] [uniqueidentifier] NULL,
CONSTRAINT [PK_History] PRIMARY KEY CLUSTERED ( [HistoryId] ASC )
)
CREATE TABLE [dbo].[Messages](
[MessageId] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_Messages] PRIMARY KEY CLUSTERED ( [MessageId] ASC )
)
CREATE TABLE [dbo].[Drafts](
[DraftId] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_Drafts] PRIMARY KEY CLUSTERED ( [DraftId] ASC )
)
In a short description the solution you have used is called:
Polymorphic Association
Objective: Reference Multiple Parents
Resulting anti-pattern: Use dual-purpose foreign key, violating first normal form (atomic issue), loosing referential integrity
Solution: Simplify the Relationship
More information about the problem.
BTW createing a common super-table will help you:
Is there a name for this relationship?
There is no standard name that I'm aware of, but I've heard people using the term "generic FKs" or even "inner-platform effect".
Is it just bad design?
Yes.
The reason: it prevents you from declaring a FOREIGN KEY, and therefore prevents the DBMS from enforcing referential integrity directly. Therefore you must enforce it trough imperative code, which is surprisingly difficult.
Is there a better way to design this relationship?
Yes.
Create separate FOREIGN KEY for each referenced table. Make them NULL-able, but make sure exactly one of them is non-NULL, through a CHECK constraint.
Alternatively, take a look at inheritance.
Best practice I have found is to create a Function that returns whether the passed in value exists in either of your Messages and Drafts PK columns. You can then add a constraint on the column on the History that calls this function and will only insert if it passes (i.e. it exists).
Adding non-parsed example Code:
CREATE FUNCTION is_related_there (
IN #value uniqueidentifier )
RETURNS TINYINT
BEGIN
IF (select count(DraftId) from Drafts where DraftId = #value + select count(MessageId) from Messages where MessageId = #value) > 0 THEN
RETURN 1;
ELSE
RETURN 0;
END IF;
END;
ALTER TABLE History ADD CONSTRAINT
CK_HistoryExists CHECK (is_related_there (RelatedItemId) = 1)
Hope that runs and helps lol

Shared Primary key versus Foreign Key

I have a laboratory analysis database and I'm working on the bast data layout. I've seen some suggestions based on similar requirements for using a "Shared Primary Key", but I don't see the advantages over just foreign keys. I'm using PostgreSQL:tables listed below
Sample
___________
sample_id (PK)
sample_type (where in the process the sample came from)
sample_timestamp (when was the sample taken)
Analysis
___________
analysis_id (PK)
sample_id (FK references sample)
method (what analytical method was performed)
analysis_timestamp (when did the analysis take place)
analysis_notes
gc
____________
analysis_id (shared Primary key)
gc_concentration_meoh (methanol concentration)
gc_concentration_benzene (benzene concentration)
spectrophotometer
_____________
analysis_id
spectro_nm (wavelength used)
spectro_abs (absorbance measured)
I could use this design, or I could move the fields from the analysis table into both the gc and spectrophotometer tables, and just use foreign keys between sample, gc, and spectrophotometer tables. The only advantage I see of this design is in cases where I would just want information on how many or what types of analyses were performed, without having to join in the actual results. However, the additional rules to ensure referential integrity between the shared primary keys, and managing extra joins and triggers (on delete cascade, etc) appears to make it more of a headache than the minor advantages. I'm not a DBA, but a scientist, so please let me know what I'm missing.
UPDATE:
A shared primary key (as I understand it) is like a one-to-one foreign key with the additional constraint that each value in the parent tables(analysis) must appear in one of the child tables once, and no more than once.
I've seen some suggestions based on similar requirements for using a
"Shared Primary Key", but I don't see the advantages over just foreign
keys.
If I've understood your comments above, the advantage is that only the first implements the requirement that each row in the parent match a row in one child, and only in one child. Here's one way to do that.
create table analytical_methods (
method_id integer primary key,
method_name varchar(25) not null unique
);
insert into analytical_methods values
(1, 'gc'),(2, 'spec'), (3, 'Atomic Absorption'), (4, 'pH probe');
create table analysis (
analysis_id integer primary key,
sample_id integer not null, --references samples, not shown
method_id integer not null references analytical_methods (method_id),
analysis_timestamp timestamp not null,
analysis_notes varchar(255),
-- This unique constraint lets the pair of columns be the target of
-- foreign key constraints from other tables.
unique (analysis_id, method_id)
);
-- The combination of a) the default value and the check() constraint on
-- method_id, and b) the foreign key constraint on the paired columns
-- analysis_id and method_id guarantee that rows in this table match a
-- gc row in the analysis table.
--
-- If all the child tables have similar constraints, a row in analysis
-- can match a row in one and only one child table.
create table gc (
analysis_id integer primary key,
method_id integer not null
default 1
check (method_id = 1),
foreign key (analysis_id, method_id)
references analysis (analysis_id, method_id),
gc_concentration_meoh integer not null,
gc_concentration_benzene integer not null
);
It looks like in my case this supertype/subtype model in not the best choice. Instead, I should move the fields from the analysis table into all the child tables, and make a series of simple foreign key relationships. The advantage of the supertype/subtype model is when using the primary key of the supertype as a foreign key in another table. Since I am not doing this, the extra layer of complexity will not add anything.

How do I eliminate Error 3002?

Say I have the following table definitions in SQL Server 2008:
CREATE TABLE Person
(PersonId INT IDENTITY NOT NULL PRIMARY KEY,
Name VARCHAR(50) NOT NULL,
ManyMoreIrrelevantColumns VARCHAR(MAX) NOT NULL)
CREATE TABLE Model
(ModelId INT IDENTITY NOT NULL PRIMARY KEY,
ModelName VARCHAR(50) NOT NULL,
Description VARCHAR(200) NULL)
CREATE TABLE ModelScore
(ModelId INT NOT NULL REFERENCES Model (ModelId),
Score INT NOT NULL,
Definition VARCHAR(100) NULL,
PRIMARY KEY (ModelId, Score))
CREATE TABLE PersonModelScore
(PersonId INT NOT NULL REFERENCES Person (PersonId),
ModelId INT NOT NULL,
Score INT NOT NULL,
PRIMARY KEY (PersonId, ModelId),
FOREIGN KEY (ModelId, Score) REFERENCES ModelScore (ModelId, Score))
The idea here is that each Person may have only one ModelScore per Model, but each Person may have a score for any number of defined Models. As far as I can tell, this SQL should enforce these constraints naturally. The ModelScore has a particular "meaning," which is contained in the Definition. Nothing earth-shattering there.
Now, I try translating this into Entity Framework using the designer. After updating the model from the database and doing some editing, I have a Person object, a Model object, and a ModelScore object. PersonModelScore, being a join table, is not an object but rather is included as an association with some other name (let's say ModelScorePersonAssociation). The mapping details for the association are as follows:
- Association
- Maps to PersonModelScore
- ModelScore
ModelId : Int32 <=> ModelId : int
Score : Int32 <=> Score : int
- Person
PersonId : Int32 <=> PersonId : int
On the right-hand side, the ModelId and PersonId values have primary key symbols, but the Score value does not.
Upon compilation, I get:
Error 3002: Problem in Mapping Fragment starting at line 5190: Potential runtime violation of table PersonModelScore's keys (PersonModelScore.ModelId, PersonModelScore.PersonId): Columns (PersonModelScore.PersonId, PersonModelScore.ModelId) are mapped to EntitySet ModelScorePersonAssociation's properties (ModelScorePersonAssociation.Person.PersonId, ModelScorePersonAssociation.ModelScore.ModelId) on the conceptual side but they do not form the EntitySet's key properties (ModelScorePersonAssociation.ModelScore.ModelId, ModelScorePersonAssociation.ModelScore.Score, ModelScorePersonAssociation.Person.PersonId).
What have I done wrong in the designer or otherwise, and how can I fix the error?
Many thanks!
Very late to your question, I had the same issue and discovered that the entity framework designer had identified my "ScoreId" column (relative to your PersonModelScore table) as a primary key column. I changed my setting to false for my ScoreId, and all worked well afterward.
You can set single primary key in the Entity in order to avoid this error.Right Click on the Scalar Properties of the field in the Entity and disable Entity Key if there are many primary keys.
You should create a single Identity key for each table.
ModelScore should have a ModelScoreId, PersonModelScore should have a PersonModelScoreId.
References between table should be a single field.
Your PersonModelScore table should define an Id column that is identity and primary key, then
you should create a unique key on PersonId, ModelId
as for Error 3002, i had the same problem ALL my field had been marked Entity key by EF
"Go to your .edmx file, right click on the background and select 'Mapping Details'. Click on the Table you need to edit the mappings of in your .edmx window and the details should appear in your new 'Mapping Details' window. Open Properties tab (Hit F4 to bring up the 'Properties' if not open) Click on the 'Value/Property' in your 'Mapping Details' to change the Properties displayed, and from your Properties window you can now set the 'Entity Key' value to 'False'. – Chris Paton Oct 4 '14 at 18:54"
This worked for me - Thanks
This is now part of my workflow when using EF Database First. And we have a task out to update the data model.