Map Table Column to Enum and Lookup Table to Enum - entity-framework

I am using Entity Framework 6, just release, and need to:
1 - Map a table column to an Enum;
2 - Map a lookup table (has two columns: Id and Name) to an Enum.
Is this possible in Entity Framework 6?
Thank you,
Miguel

You typically don't map table to an enum type. You just define an enum type based on what you have in your lookup table and use it without including these tables in the model. For instance for the Northwind.Categories table:
ID Name Description
1 Beverages Soft drinks, coffees, teas, beers, and ales
2 Condiments Sweet and savory sauces, relishes, spreads, and seasonings
3 Confections Desserts, candies, and sweet breads
4 Dairy Products Cheeses
5 Grains/Cereals Breads, crackers, pasta, and cereal
6 Meat/Poultry Prepared meats
7 Produce Dried fruit and bean curd
8 Seafood Seaweed and fish
You would create the following enum type
public enum Categories
{
Beverages = 1,
Condiments = 2,
Confections = 3,
Dairy_Products = 4,
Grains_Cereals = 5,
Meat_Poultry = 6,
Produce = 7,
Seafood = 8,
}
(make sure that enum values correspond to the values in your database) and you would use it in your app without including the Categories table - i.e. you would use this enum type as the type of the properties that are foreign keys to the Categories table in the database. Alternatively - e.g. if you need descriptions - you would create an entity corresponding to the Categories table and use the enum (as defined above) as the key property type. Then again you would use the enum type for all properties that in the database are foreign keys to the Categories table.

Related

Adding elements on many-to-many relation

I am making a project where (from the perspective of school) you can calculate each student average.
You can register a student (first entity) on a screen and subjects (second entity) on another screen.
Student has name, email, grade and average as atributes, and Subjects has name. They relate many-to-many with each other.
I am trying to create a copy of subjects list to each student, then on each student i can register a grade to each subject. Like this:
Model concept
Model:
!https://imgur.com/gmXyR5j
I've created a singleton of subjects since it is used more than one location:
import Foundation
import CoreData
class SubjectsManager {
static let shared = SubjectsManager()
var subjects: [Subject] = []
func loadSubject(with context: NSManagedObjectContext) {
let fetchRequest: NSFetchRequest<Subject> = Subject.fetchRequest()
let sortDescritor = NSSortDescriptor(key: "name", ascending: true)
fetchRequest.sortDescriptors = [sortDescritor]
do {
subjects = try context.fetch(fetchRequest)
} catch {
print(error.localizedDescription)
}
}
func deleteSubject(index: Int, context: NSManagedObjectContext) {
let subject = subjects[index]
context.delete(subject)
do {
try context.save()
subjects.remove(at: index)
} catch {
print(error.localizedDescription)
}
}
private init() {
}
}
And, on my student screen, i've tried many thing but nothing is working.
The to-many relation of student with subject is called registeredSubjects
I've created a NSSET called subjectsManagerSet to get values from the singleton, but it not working. Here what i've tried so far:
subjectManagerSet.addingObjects(from: subjectsManager.subjects)
Also tried to create a for loop of subjectManager.subjects to add on subjectManagerSet but it's not working too.
About errors, when i get samples from xcode output, it keep showing that subjectManagerSet did not get values from subjectManager.subject
Error message:
2019-09-26 20:38:16.983725-0300 MyAverage[1734:62290] Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file /Users/vitorgomes/Desktop/Mentorizacao/MyAverage/MyAverage/Controllers/StudentsViewController.swift, line 119
(lldb) po subjectManagerSet
0 elements
The expected result is that i want a copy of subjects for each student instance, then i can add grades for each subjects for each student.
The expected result is that i want a copy of subjects for each student
instance, then i can add grades for each subjects for each student.
I am not addressing your problem as stated at the beginning of your question, but the one stated at the end, per the quote above.
I would encourage you to reconsider the structure of your model.
Perhaps something like this?
In this proposed model, you're able to assign to an object of the entity Enrolment:
a grade (and date) via these attribute properties;
a student via the one-to-many relationship property with a Student entity;
a subject via the one-to-many relationship property with a Subject entity.
In the following examples, I assume Core Data generated NSManagedObject subclasses - that is - in the Data Model Inspector, set the value for Codegen = Class Definition (default).
(Personally and as an aside, I prefer to manually write NSManagedObject subclasses for each of my entities and use Set rather than the NSSet, as I find it subsequently a lot easier to maintain type integrity in my code. But I have not done that here as most people who are new to Core Data will use the default for Codegen noted above.)
You're able to access these values in the following manner...
let student = Student()
print("Student name is: \(String(describing: student.name))")
if let studentEnrolments: NSSet = student.studentEnrolments {
for item in studentEnrolments {
if
let enrolment = item as? Enrolment,
let subjectName: String = enrolment.subject?.name {
print("Subject name for this student is: \(subjectName)")
}
}
}
Its easy to assign a subject enrolment to a student...
let enrolment = Enrolment()
let subject = Subject()
enrolment.subject = subject
student.addToStudentEnrolments(enrolment)
Then now or later, a grade can be applied to the enrolled subject...
let grade: String = "A"
enrolment.grade = grade
Of course the average becomes a mathematical function based on the sum of all grades for each student, divided by the count. This is in my humble opinion, better constructed as it is needed, rather than saved as an attribute with each Student object.
Update
Im updating my answer to include a little database theory to explain my proposed object model.
According to Wikipedia, Database normalisation is...
the process of structuring a relational database
in accordance with a series of so-called normal forms in order to
reduce data redundancy and improve data integrity.
What does this practically mean to me? It means breaking my data down into its most discrete and unique parts, so that, in theory, I never need to enter any unique piece of data more than once.
Let me use a simple table example as a means of explaining this, as it might be set out in a spreadsheet (or your model concept):
Original Data
TABLE 1
A B C
1 STUDENT SUBJECT GRADE
2 Student1 Mathematics 8.8
3 Student1 Physics 7.0
4 Student1 Biology 6.0
5 Student2 Mathematics 5.0
6 Student2 Physics 9.0
7 Student2 Biology 7.0
Normalised Data
TABLE 1 TABLE 2 TABLE 3
A B C A B A B
1 STUDENT SUBJECT GRADE ID STUDENT ID SUBJECT
2 1 1 8.8 1 Student1 1 Mathematics
3 1 2 7.0 2 Student2 2 Physics
4 1 3 6.0 3 Biology
5 2 1 5.0
6 2 2 9.0
7 2 3 7.0
The normalised data uses relationships between the three tables. It stores the ID (as a primary key) of each STUDENT and each SUBJECT, instead of the actual words. This is obviously far more efficient in many different ways, including but not limited to: bytes of stored data, ability to index, speed of data retrieval.
When you set a relationship property in your Core Data object model graph, you are doing the same thing...
So for your example, the Core Data object model graph Entity replaces TABLE. The Core Data framework automagically inserts a primary key column into the SQLite database for us when it constructs the tables and later a primary key unique integer when we programmatically add rows (records, a.k.a instances of an entity). While we don't have direct access to that as a developer (using Core Data), the Core Data framework allows us to build one-to-one, one-to-many and many-to-many relationships between two entities, that achieves the same outcome.
Enrolment Student Subject
A B C A B A B
Rel. Rel. Att. Rel. Att. Rel. Att.
∞ ∞ 1 1
Z_PK Student Subject grade Z_PK name Z_PK name
1 1 1 8.8 1 Student1 1 Mathematics
2 1 2 7.0 2 Student2 2 Physics
3 1 3 6.0 3 Biology
4 2 1 5.0
5 2 2 9.0
6 2 3 7.0
Att. = Entity Attribute;
Rel. = Entity Relationship;
∞ = many side of one-to-many Relationship (<<-);
1 = one side of one-to-many Relationship (-->)
Any questions, let me know?

EF Core: Multiple enum discriminators per TpH

AbstractA
/ \
AbstractB AbstractC
| |
ConcreteBA ConcreteCA
There is an enum discriminator which defines whether it is "B" or "C" and an additional enum which describes whether its "BA" or "CA"
If enum 1 has value 1 and enum 2 has value 1 then it's "BA"
If enum 1 has value 2 and enum 2 has value 1 then it's "CA"
The Concrete classes BA and CA have class which links to a separate table
Can I create multiple discriminators to help define this for EF core?

What column type is required when using ElementCollection with jpa?

I have a simple class with a column that is technically a List
#Entity
#Table(name='hat')
class Hat {
#Id
String id = UUID.randomUUID()
#ElementCollection
List<String> wat
}
Right now when I use either a varchar(500) or character varying(500) the PSQL code that pulls this entity out of the database explodes
org.postgresql.util.PSQLException: ERROR: relation
"hat_wat" does not exist
An element collection is not stored in a single column. It's stored in a separate table, just as if you have a OneToMany, except there is no identifier for the many side. Suppose the Hat foo has 2 wats "bar" and "baz":
hat table: hat_wat table:
id hat_id wat
----- ---------------
foo foo bar
foo baz
That allows querying the hats to find, for example, all the hats having "bar" in their list of wats. Trying to store multiple string in a single column is really not a good idea. It violates the first normal form rules.

How to create a PostgreSQL column that is a set of enum values?

I like that I can create new enum types in PostgreSQL. But what if I want a column value that is a set of enum values. Do I need to implement that manually with an integer column type and bitwise operators, or is there a way to keep using the enums by name?
CREATE TYPE foo AS ENUM ('none', 'loud', 'bright', 'cheap')
CREATE TABLE t (
id serial,
properties [set of foo?]
)
...
SELECT * FROM t;
1 loud
2 loud, cheap
3 bright
4 none
...
You can use an array:
CREATE TYPE foo AS ENUM ('none', 'loud', 'bright', 'cheap');
CREATE TABLE t (
id serial,
properties foo[]
);

How can I get data from two tables?

I am using Hibernate and PostgreSql. In hibernate I have two classes like:
Mobile(id, name, serial no,model_no)
Model(id, description, value)
Now Model class's values are stored in Mobile class (model_no). This Mobile class doesn't have any reference to Model class.
In Model class has data like:
Modal
======
id description value
1 aaaa 1
2 bbbbb 2
3 ccccc 3
4 ddddd 12
5 eeee 40
Here this value is being stored in Mobile table. In Mobile table I have model_no as 0 (which is not in Model, I don't want to put that value in Model table, because if I put I needs to change lot of code.
Now what I want a query to get the out put like
value description
---- ------------
0 UNKNOWN
1 aaaa
2 bbbbb
3 ccccc
4 ddddd
5 eeee.
like this. To get the all model_nos I can use a query like
select modal_no from Mobile
where modal_no in(select value from Modal) or model_no = 0
but here I what the description also which is in Model table. Can anybody help?
Thank u bro for your response, as i mentioned this Mobile table(Hibernate Mobile class) don't have reference to the Model table(in hibernate Model class). If i have reference to Model in Mobile class then your answer will be 100% correct. In my Mobile class this model_no is integer value. If i use your query in hql i will get the exception like "path expected". I want Hql(or sql) query to get the output with 0 value.
my hibernate Mobile class is like this
class Mobile {
int id;
int model_no; // this model_no has 0 + modal_no values(1,2,3,12,42).
// some references like
Manufacture manf;
SerialNo serialno;
Customer cust;
getters and setters
}
My Hibernate Model class is like ...
class Model{
int id;
String description;
int value; this column has 1,2,3,12,42. it don't have 0.
setters and getters.
}
A left join would accomplish that:
select Mobile.modal_no
, Modal.description
from Mobile
left join
Modal
on Mobile.model_no = Modal.value