I have to tables created theme by Entity Framework for example:
Book Table:
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public int Book_Type_Id { get; set; }
}
Book_Type Table:
public Book_Type
{
public int Id { get; set; }
public string Title { get; set; }
}
I will store some limited values for example Novel and education and ... in Book_Type table But in this way searching string can has spelling error. I think it's cannot be correct and may be exist a way for example use a predefined list and store specific Book type value as string.
what is your opinion?
You maybe looking for an Enum. A value type data type, where you decalre all distinct possible value. In order to have those name constant and easly refered to.
Ef does support the enum. And it's pretty strait forward. Declare then Use it.
Here is a msdn article and video about
MSDN: Enum Support - Code First
Related
I have the bellow entities:
public class Notification
{
public int Id { get; set; }
public string Title { get; set; }
public Guid RefId { get; set; }
public Object Ref { get; set; } // << The navigation property: Sometime its type is Poll and sometime is Test, maybe I add other types too
public NotifTypes Type { get; set; }
}
public enum NotifTypes
{
Poll=1,
Test=2,
// Other NotifTypes here
}
//-------------------------------------------------------------------
public class Test
{
public int Id { get; set; }
public string Title { get; set; }
public IEnumerable<Notification> { get; set; }
}
public class Poll
{
public int Id { get; set; }
public string Answer1 { get; set; }
public string Answer2 { get; set; }
public IEnumerable<Notification> { get; set; }
}
OK,
When the Type property of Notification object is equal Poll, the RefId will fill by a PollId
When type is equal Test, the refId will fill by a TestId.
Now I want conditionally include the related Poll or Test in Ref property. How should I implement it?
I want prevent to add separate Ids like PollId, TestId and.... to Notification because I'm sure that each time just one of them has value, so I want have one RefId and one Ref property instead of them.
I don't know EntityFramework, but you asked me to answer this.
You're basically reinventing polymorphic-associations which is not a good relational design. You can read a few of my past answers about this concept:
Possible to do a MySQL foreign key to one of two possible tables?
Why can you not have a foreign key in a polymorphic association?
MySQL - Conditional Foreign Key Constraints
I tend to answer MySQL questions, but the answer is the same for any other brand of RDBMS. The fact that you cannot declare an actual foreign key constraint that references multiple tables should be a clue that this design is not right.
The easiest solution from a data modeling perspective is to create an independent attribute for each of your potential table references. All but one of these will be NULL on a given row.
I have no idea how EntityFramework might support this. #AluanHaddad's advice sounds good.
Try not to break relational concepts. Down that path is the Inner-Platform Effect antipattern.
Can somebody explain this to me? How it would work and what it does. I am creating a c# student registration form.
I created my class:
public class Course
{
public string Number { get; set; }
public string Name { get; set; }
}
Just confused on the list part and what it does....
The goal is to think in an object oriented paradigm. Your course will have the following:
Number (Id)
Name
List Of Students (Collection)
Based on the following description, your model isn't complete. As I indicated above, think in an object oriented paradigm. If I have a school, how would I govern the courses and students?
public class Student : IEntity<int>
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Course : IEntity<int>
{
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<Student> Students { get; set; }
}
The initial foundation exist, for every course I'll have a collection of students enrolled in the course. That would be the foundation, to build upon the example though:
How would the model change, if I have to track courses by school?
How would the model change, if I need to append a numeric grade for a student?
These questions, will impact your model's. As I denoted above, if you think in the paradigm of objects and how they relate together it will help you build your initial objects but the relational data tables in the database as well.
Also, without the entire diagram we would be assuming or inferring our own interpretation, hopefully this will assist you.
This is usually how you construct entities, mapping the id to a int in the database
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Address
{
public int PersonId { get; set; }
public string Street { get; set; }
}
I started implementing a system like this for my entities:
public enum PersonId : int { }
public class Person
{
public PersonId Id { get; set; }
public string Name { get; set; }
}
public enum AddressId : int { }
public class Address
{
public AddressId Id { get; set; }
public PersonId PersonId { get; set; }
public string Street { get; set; }
}
Mapping the enum to a int (or other struct) in the database.
This way i can scope method and code, to not mistakenly ask for a specific address with a persons int id, as a int is always a int.
As i understand, F# have something similar to this built in?
My question here is, do anyone know if this will affect performance with entity framework in any way?
At the IL level, an enum is just an integer anyway; any decent runtime-based meta-programming library should know to go directly to the int without any intermediate conversion - and I would be amazed if EF got this wrong.
To me, however, the real problem is more a semantic one; that is not really what enums are intended to mean. You might additionally get problems in some serialization and UI tools (when they are looking how to represent or parse an AddressId with value 100124, etc).
Personally, I wouldn't do this. Mixing up what values mean is indeed a potential problem, but the answer to this is not abusing the type system. I "get it" that some languages offer aliases / type-defs that allow you to do this in a checked fashion, but an enum is not just a checked alias - it means more than that.
I've got some objects that look like this:
abstract public class Field
{
public int Id { get; set; }
public string Name { get; set; }
public int Ordinal { get; set; }
}
[Table("DropDownField")]
public class DropDownField : Field
{
public virtual List<FieldOption> Options { get; set; }
}
[Table("RadioButtonField")]
public class RadioButtonField : Field
{
public virtual List<FieldOption> Options { get; set; }
}
public class FieldOption
{
public int Id { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
In my database, it ends up creating the a FieldOptions table using Code First. However, it creates the following columns:
Id
Name
Value
DropDownField_Id
RadioButtonField_Id
What I'd like to see is just one Field_Id in this table since the Id of a field has to be unique across the different types of fields.
Is there a way to do this? I've done some searching but I must not know the right search terms to use to find the answer.
imho, what you want, from a relational database point of view, is a column (Option.FieldId) being a foreign key to 2 tables DropDownField and RadioButtonField.
That is whenever you insert an option, FieldId must reference an existing DropDownField AND an existing RadioButtonField.
That is at least weird.
I don't think this can/should be achieved.
I have a large application that has many drop down fields in the system that have just a small set of values. It's not really worth it to have a table for each of these values and a separate page to handle crud for each of the drop down types. WHat I did is make a DropDowns table that has a discriminator column to discern which type of drop down it is.
I define each type in the code by just creating a class that derives from the drop down class.
My CRUD manager is able to use reflection to allow the user to add a value to any of the drop downs.
So far so good.
Now I want to be able to EXTEND a particular drop down, so that it can have properties that the other drop downs don't have.
For instance, the list of payment terms. I'd like to add a field for the deposit percentage, so that I can use that to calculate the deposit.
My goal is to have all of the values stored in a single table, similar to the way drop down values are.
In SQL, I would just have a table called DropDownExtendedProperties with fields: DropDownID, PropertyName, PropertyValue with the DropDownID linking the Extended Property to the dropdown value that it accompanies.
In C# / EF I was able to get the correct database structure using 1 to 0 or 1, BUT once I make subtypes of DropDownExtendedProperty, the dropdown type makes a direct relationship to that table for the subtype.
I tried fooling with a one to many but I don't see a way out of this other than just pulling the types that need extended properties out of the DropDown table and making their own table & CRUD. I understand that at this point that is actually the simpler solution, but I think what I'm trying to do should be possible and I just can't figure out how.
I've included some code below, but I have tried the relationship a few different ways, and I am posting the most recent attempt.
public class DropDownExtendedProperty
{
[Key]
public int PropertyID { get; set; }
[ForeignKey("DropDown")]
public int DropDownID { get; set; }
public virtual DropDown DropDown { get; set; }
public int? IntValue { get; set; }
public string StringValue { get; set; }
public FieldType FieldType { get; set; }
public DateTime? DateValue { get; set; }
public float? MoneyValue { get; set; }
}
public class DropDown
{
[Key]
public int ID { get; set; }
[Required]
public string Value { get; set; }
public virtual List<DropDownExtendedProperty> ExtendedProperties { get; set; }
}
public class PaymentTerms : DropDown
{
public virtual DaysToPay DaysToPay { get; set; }
}
public class DaysToPay : DropDownExtendedProperty
{
}
public enum FieldType
{
Date,
String,
Int,
Money
}
modelBuilder.Entity<DropDownExtendedProperty>()
.HasRequired(a => a.DropDown)
.WithMany();
My goal with this is to be able to define SINGLE value for each DropDown that has a specific type THROUGH the more abstract DropDownExtendedProperty. So in our case, the PaymentTerms dropdown value of "Net30" can have an accompanying int value in the DaysToPay field which I can use in the code for calculations.