I have some data class generated from the DB:
[Table("appdb.apptable")]
public partial class apptable
{
[Key]
public int Id { get; set; }
public int Sum { get; set; }
public string Comment { get; set; }
}
How, I need to support different table in a generic way.
The table name the same, but it does not contain Comment field.
I need somehow to make the Comment property optional.
How can I make an existent DB field optional in Entity Framework?
Related
How should I design entity classes for tables? Classes map their relationships? How should I modify it? I don't want to use code first or DB first, just write code manually to add relationships.
public partial class Ip
{
public int Id { get; set; }
public string Ip1 { get; set; }
public int UserId { get; set; }
}
public partial class U
{
public int Id { get; set; }
public string UserName { get; set; }
public string Pwd { get; set; }
}
Expect of Code First and Database First we have Model First in entity framework.
First idea you can add relation between tables on database (server side handling).
Second idea you can write sql query code then execute in SeedData Method. but you need to check relation not exist that table.
Say I have an abstract Person Table, and derived tables, Student and Teacher, Admin etc. Person has a enum property PersonType with values for each derived class, and a virtual collection Events.
Now when Entity Framework creates the Events table, it creates a column for each class derived from Person, eg. Student_Id, Teacher_Id, Admin_Id etc.
If I have a dozen derived classes, then that's a dozen extra columns, only 1 of which is ever in use.
How do I tell Entity Framework to instead refer to the PersonType property in conjunction with the Id instead of creating all these unnecessary columns?
So it has simple solution with DataAnnotations, if i understood you correctly.
[Column("TableID")]
I'm going to give you a working example from a project of mine. So i have an abstract Class which has called Trip. Cruise and Hotel classes are derived from Trip class. I need to Store Comments on a single table and as you have concerned i dont need CruiseID nor HotelID on Comments table so i named TripID with Column Annotation and entity framework will create table magically if we annotated well
public class Comment
{
public int CommentID { get; set; }
[Column("TripID")]
[ForeignKey("Trip")]
public int TripID { get; set; }
public virtual Trip Trip { get; set; }
public string Text { get; set; }
}
public class CruiseComment : Comment
{
[Column("TripID")]
[ForeignKey("Cruise")]
public int CruiseID { get; set; }
public virtual Cruise Cruise { get; set; }
}
public class HotelComment : Comment
{
[Column("TripID")]
[ForeignKey("Cruise")]
public int HotelID { get; set; }
public virtual Hotel Hotel { get; set; }
}
It's not necessary to use ForeignKey annotation. It's needed when you have different namings.
I am using EF 6 Code First, I don't understand why one column is not created for a property of my Model.
Here is the first class :
public class Original
{
public int ID { get; set; }
public string Nom { get; private set; }
public Historique Historique { get; private set; }
public Traduction Traduction { get; private set; }
}
And here is the second class :
public class Traduction
{
public int ID { get; set; }
public Utilisateur Traducteur { get; private set; }
public Original Original { get; private set; }
public string Content { get; private set; }
}
EF doesn't create the FK column for Traduction and Original. (The Traduction table doesn't contains a FK column for Original and vice versa) but it perfectly creates all the other column and FKs.
I am playing with Fluent API to set up the relationships. I have tried both to rely on the automatic conventions, and to explicitly configure the relation with :
modelBuilder.Entity<Original>().HasRequired(o => o.Traduction).WithRequiredPrincipal(t=>t.Original).WillCascadeOnDelete(true);
But the columns are still not created.
Thank you for your help
Update
I don't know if it is useful but I would like to add one information, my Dbset are defined like this in the context class :
public DbSet<Traduction> Traductions { get; set; }
public DbSet<Original> Originaux { get; set; }
"Originaux" if the French plural for "Originals". However I have noticed that the Table created by EF is Named "Originals", and doesn't follow the name of the DbSet. I don't know, perhaps it might be a cause of the problem.
As Dismissile said, EF doesn't create an extra column to hold the foreign keys because it is a one-to-one relationship. This is a normal behaviour and nothing is actually wrong.
Consider the following model classes:
public class Thing
{
public int Id { get; set; }
[Required]
public Text Subject { get; set; }
[Required]
public Text Body { get; set; }
}
public class Text
{
public int Id { get; set; }
public string Value { get; set; }
}
The model is simple - each Thing must reference to two Text entities. Each Text entry at any point in time should be referenced only by a single entity of any other type (Thing is not the only one).
Is it possible to configure EF5 to automatically delete all referenced Texts when Thing gets deleted (via context.Set<Thing>().Remove), or should it be done with a database trigger?
You just need to configure CASCADE DELETE at database level and don't have to do anything special at Entity framework level.
Suppose you have
public class A
{
public string _myString;
}
And this context:
public class MyContext: DbContext
{
public DbSet<A> myASet{ get; set; }
}
Now, is there a way to tell EF to generate an identity column for myASet?
I don't want to add an ID field to class A, so I wonder if EF could do this.
Many thanks,
Juergen
You must add ID column to your class if you want to have it in the database. Also in EF each entity must have mapped primary key.
EF will only use columns which are actually in your model classes, so you have to put all the ones you want in yourself. This includes identity columns for primary keys.
If you have an entity called Product and a property called 'ProductId' , EF will automatically add the identity column as it looks for entity name + Id by convention.
You can use a column that does not comply with the convention by adding a [key] attribute above the desired property.
In the example below. An identity column will be created for ProductId.
public class Product
{
public int ProductId { get; set; }
public string Name { get; set; }
public string CategoryId { get; set; }
public virtual Category Category { get; set; }
}
In this example, the column 'MyId' will be created as an identity.
public class Product
{
[key]
public int MyId { get; set; }
public string Name { get; set; }
public string CategoryId { get; set; }
public virtual Category Category { get; set; }
}