Passing Generic Class' Property to ColumnAttribute in Code First Migration - entity-framework

I have an abstract class inherited in 3 POCO objects:
public abstract class BaseObject
{
public virtual int Id { get; set; }
}
public class Post : BaseObject
{
public string Name { get; set; }
public virtual ICollection<PostCategory> PostCategory { get; set; }
}
public class Category : BaseObject
{
public string Name { get; set; }
public virtual ICollection<PostCategory> PostCategory { get; set; }
}
public class PostCategory
{
[Key]
[Column("Id", Order = 0)]
public int PostId { get; set; }
[Key]
[Column("Id", Order = 1)]
public int CategoryId { get; set; }
public string Value { get; set; }
public virtual Post Post { get; set; }
public virtual Category Category { get; set; }
}
However, whenever I do 'add-migration' in Package Manager Console, I get error:
Schema specified is not valid. Errors: (30,6) : error 0019: Each
property name in a type must be unique. Property name 'Id' was already
defined.
Basically complaining the ColumnAttribute having same property name (Id property in PostCategory object).
I need the property name to be the same for creating generic class that is used in generic Repo class. That's why I have the Id in an abstract class. But, this gives me error on CF migration part. Is there a way to get around this?
Thanks!

The ColumnAttribute attribute, sets the name generated in the SQL server. Obviously the column Id cannot be generated twice.
Simply remove the ColumnAttributes, allowing the server to generate the PostCategory table peacefully.

Related

The entity type required a primary key to be defined - but there is

I probably have a fairly trivial problem with EF configuring 1 table. This is how my class looks like:
public class Task
{
[Key]
public int Id { get; set; }
[Required]
public string Description { get; set; }
[Display(Name = "Modification Date")]
public DateTime ModificationDate { get; set; }
[Required]
public bool IsDone { get; set; }
}
This is how dbContext looks like:
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions options) : base (options) { }
public DbSet<Task> Tasks { get; set; }
}
And while creating migration I get this error:
The entity type 'Task' requires a primary key to be defined. If you intended to use a keyless entity type, call 'HasNoKey' in 'OnModelCreating' [...]
But as you can see I have an attribute [Key], the property is public and has a setter, what could be the problem?
Ok, that was the dumbest mistake in a long time. It turned out the context was using the Task system class instead of my model class...

How do i create One-to-One mapping in EF 6 using Data Annotation approach

I am using EF 6.1.1.
I am unable to figure out how to create One-to-One relationship between two classes/tables with both entities have their owns PKs. I originally posted question link but could not get much help on it OR i am not able to get it. So, here i am putting my question in simple way.
Appreciate if someone can share thoughts on it.
My Requirement:
I would like create One-To-One relationship between Principle and Dependant with 'Id' from Principle class acts as Foreign Key in dependant class.
Principle Class
public class Student
{
public string FullName {get; set;}
}
Dependant Class
public class StudentReport
{
public string RollNumber { get; set; }
public string StudentType { get; set; }
}
Add PKs – EF requires this:
public class Student
{
public int Id { get; set; }
public string FullName { get; set; }
}
public class StudentReport
{
public int Id { get; set; }
public string RollNumber { get; set; }
public string StudentType { get; set; }
}
Note that EF 5 and later supports naming conventions: Id indicates a primary key. Alternately, it also supports the name of the class followed by "Id", so the above keys could have been StudentId for Student and StudentReportId for StudentReport, if you wished.
Add the foreign relation as a navigation property to at least one of the tables – in this case, you stated that StudentReport is the dependent, so let's add it to that one:
public class Student
{
public int Id { get; set; }
public string FullName { get; set; }
}
public class StudentReport
{
public int Id { get; set; }
public string RollNumber { get; set; }
public string StudentType { get; set; }
public Student Student { get; set; }
}
Again – by naming convention – EF determines that a single Student property on StudentReport indicates that this is a navigational property associated with a foreign key. (By defining only the Student property, but no foreign key property, you are indicating that you don't care what EF names the associated FK ... basically, you're indicating you'll always access the related Student via the property.)
If you did care about the name of the FK property, you could add it:
public class Student
{
public int Id { get; set; }
public string FullName { get; set; }
}
public class StudentReport
{
public int Id { get; set; }
public string RollNumber { get; set; }
public string StudentType { get; set; }
public int StudentId { get; set; }
public Student Student { get; set; }
}
Again – by naming convention – EF determines that StudentId is the FK associated with the Student property because it has the class name, "Student", followed by "Id".
All of this, so far, has been using conventions as defined in Entity Framework Code First Conventions, but Data Annotations are also an option, if you wish:
public class Student
{
[Key]
public int Id { get; set; }
public string FullName { get; set; }
}
public class StudentReport
{
[Key]
public int Id { get; set; }
public string RollNumber { get; set; }
public string StudentType { get; set; }
[ForeignKey("Student")]
public int StudentId { get; set; }
public Student Student { get; set; }
}
Doing this is actually a good idea, because it makes clearer your intent to other programmers that might not be aware of EF Conventions – but can easily infer them from simply looking at EF Data Annotations – and is still less cumbersome than Fluent API.
UPDATE
I just realized, I left this as a one-to-many, with enforcement of the one-to-one relationship being left to do in the code using this model. To enforce the one-to-one in the model, you could add a navigation property to the Student class going the other way:
public class Student
{
public int Id { get; set; }
public string FullName { get; set; }
public StudentReport StudentReport { get; set; }
}
public class StudentReport
{
public int Id { get; set; }
public string RollNumber { get; set; }
public string StudentType { get; set; }
public Student Student { get; set; }
}
However, that's going to break, because EF doesn't know which entity to insert first on an add. To indicate which is dependent, you have to specific that the dependent class' PK is the FK to the principal class (this enforces one-to-one because – in order for a Student/StudentReport pair to be associated – their Id properties must be the exact same value):
public class Student
{
public int Id { get; set; }
public string FullName { get; set; }
public StudentReport StudentReport { get; set; }
}
public class StudentReport
{
[ForeignKey("Student")]
public int Id { get; set; }
public string RollNumber { get; set; }
public string StudentType { get; set; }
public Student Student { get; set; }
}
or, using the full set of Data Annotations from earlier:
public class Student
{
[Key]
public int Id { get; set; }
public string FullName { get; set; }
public StudentReport StudentReport { get; set; }
}
public class StudentReport
{
[Key, ForeignKey("Student")]
public int Id { get; set; }
public string RollNumber { get; set; }
public string StudentType { get; set; }
public Student Student { get; set; }
}

entity framework insert only some columns

I have a POCO class
public class Main
{
public int ExstraColumn{ get; set; }
}
public class User : Main
{
[Key]
public int Id { get; set; }
public int? Age { get; set; }
}
public class News : Main
{
[Key]
public int Id { get; set; }
public int? ReadCount { get; set; }
}
now i want entity framework inserts only age column in user. But it gives invalid column name ExstraColumn
how to tell entity framework that ExstraColumn field is only special usage?
You can use the [NotMapped] attribute in the System.ComponentModel.DataAnnotations namespace.
http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.schema.notmappedattribute(v=vs.110).aspx
Denotes that a property or class should be excluded from database
mapping.

Entityframework 4.3 codefirst using TPT and discriminator

I have these three models:
public class Equipment
{
public int ID { get; set; }
public string title { get; set; }
}
[Table("Vessels")]
public class Vessel:Equipment
{
public string Size { get; set; }
}
[Table("Tubes")]
public class Tube : Equipment
{
public string Pressure{ get; set; }
}
I want to show a list of Equipments with 2 columns title and type.
for example:
Title Type
------ -------
101-1 vessel
101-2 vessel
102-3 tube
I don't know how to make a discriminator column in Equipments to show the type of each equipments.
EDITED
If I have a discriminator in Equipment entity like:
public class Equipment
{
public int ID { get; set; }
public string title { get; set; }
public string type{ get; set; } //as discriminator
}
I can get the query in controller or repository like this:
var equipments=from e in db.Equipments
select e;
You cannot make discriminator column in terms of EF mapping - TPT inheritance doesn't support it because the discriminator is a subtable. You can try to use something like:
public abstract class Equipment
{
public int ID { get; set; }
public string title { get; set; }
[NotMapped]
public abstract string Type { get; }
}
and override Type property in subtypes to get the correct name. You will not be able to use that property in Linq-to-Entities queries because it is not mapped.

One to One Relationship on Primary Key with Entity Framework Code First

I'm currently getting the following error when trying to create an one to one relationship using Code First:
System.Data.Edm.EdmAssociationEnd: : Multiplicity is not valid in Role 'C001_Holding_Teste_C001_Holding_Source' in relationship 'C001_Holding_Teste_C001_Holding'. Because the Dependent Role refers to the key properties, the upper bound of the multiplicity of the Dependent Role must be 1.
My entity definitions are the following:
[Table("C001_Holding", Schema = "Cad")]
public partial class C001_Holding
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int C001_Id { get; set; }
[MaxLength(16)]
public string C001_Codigo { get; set; }
[MaxLength(100)]
public string C001_Descricao { get; set; }
}
public class C001_Holding_Test
{
[Key]
public int C001_Id { get; set; }
[MaxLength(100)]
public string C001_TestInfo { get; set; }
[ForeignKey("C001_Id")]
public virtual C001_Holding C001_Holding { get; set; }
}
I didn't want to use Fluent to create these relationships, does anyone knows why this is happening?
Tks.
It is possible to place the ForeignKey attribute either on a navigation property and then specify the name of the property you want to have as the foreign key (that's what you did). Or you can place it on the foreign key property and then specify the name of the navigation property which represents the relationship. This would look like:
public class C001_Holding_Test
{
[Key]
[ForeignKey("C001_Holding")]
public int C001_Id { get; set; }
[MaxLength(100)]
public string C001_TestInfo { get; set; }
public virtual C001_Holding C001_Holding { get; set; }
}
For some reason this second option works while the first throws an error. (It feels like a bug to me because both options should represent the same relationship. Or there is actually a semantic difference which I don't see...)