I like to reference to a specific entry in a database. Is there a data annotation, which I could use
E.g.
public class Address
{
public int CityId {get; set;}
}
public class City
{
public int id {get; set;}
}
So the Address.CityId references the City.id.
And how can I reference to Table Columns via data annotations.
Please refer this link .
https://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-a-more-complex-data-model-for-an-asp-net-mvc-application
in that read Topic : The Key Attribute
What you want is called One-To-One entity mapping. You can create navigation property in your Address class as follows:
public class Address
{
[Key]
public int AddressID {get;set;}
public int CityID {get; set;}
[ForeignKey("CityID")]
public City City {get;set;}
}
public class City
{
[Key]
public int CityID {get; set;}
}
Add ForeignKey attribute to your navigation property to create mapping through foreign key. And do not forget to define key attributes in each EF model.
More details on Entity Framework home page: Configure One-to-Zero-or-One Relationship
Related
Following the ForeignKey docs, and multiple examples online I was under the influence that if I give my property (foreign key) this attribute, it would get replaced in a Html.Display call by the first textual property of the parent table.
This doesn't happen and all I get is the same foreign key field.
Does this work in db first applications, and if so, how do I make it work (using ForeignKey)?
Thanks.
EDIT: Or is this Scaffolding exclusive behaviour?
UPDATE: Example code:
// Entity model in Case.cs
public partial class Case
{
public int ID {get; set;}
public string Description {get; set;}
public int Classification_ID {get; set;}
public virtual Classification Classification {get; set;}
}
// Entity model in Classification.cs
// It's a lookup table
public partial class Classification
{
public int ID {get; set;}
public string Label {get; set;}
}
// File with partials
[MetadataType(typeof(CaseMetadata))]
public partial class {}
public class CaseMetadata
{
[ForeignKey("Classification")]
public int Classification_ID {get; set;}
}
Here is my Entity:
public class StackImage: ICollection<StackFile>
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public virtual Guid Id { get; set; }
private IList<StackFile> StackFiles { get; set; } = new List<StackFile>();
public StackImage()
{
}
[...] // Implementation of ICollection
}
public class StackFile
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public virtual Guid Id { get; set; }
public string Url { get; set; }
public int Position { get; set; }
public StackFile(){}
}
stackImage.Add(new StackFile(url));
stackImage= await _stackImageRepository.UpdateAsync(stackImage);
await _unitOfWork.SaveChangesAsync();
In this sample after UpdateAsync, the StackImage Id is not generated (stackImage.Id == default) but the StackFile Id is correctly generated (stackImage[0].Id == default)
Did you already noticed this problem? My guess is, EF Core see StackImage as a list and doesn't try to generate a new Guid. How to fix this issue?
EDIT:
From what I can read on the web and by responses I received, It seems not possible to do it. If someone has the solution, please let us know :)
It seems to me that you want to design a database with (at least) two tables. A table with StackImages and a table with StackFiles.
You want to design a one-to-many relation between StackImages and StackFiles: every StackImage has zero or more StackFiles, every StackFile belongs to exactly one StackImage. In a database this is implemented using a foreign key.
Hence, it is not true that a StackImage is a StackFile. However, you can say that a StackImage has some StackFiles.
Following the entity framework code first conventions your classes should be similar to:
class StackImage
{
public Guid Id {get; set;}
...
// every StackImage has zero or more StackFiles (one-to-many):
public virtual ICollection<StackFile> StackFiles {get; set;}
}
class StackFile
{
public Guid Id {get; set;}
...
// every StackFile belongs to exactly one StackImage, using foreign key:
public Guid StackImageId {get; set;}
public virtual StackImage StackImage {get; set;}
}
finally the DbContext:
class MyDbcontext : DbContext
{
public DbSet<StackImage> StackImages {get; set;}
public DbSet<StackFile> StackFiles {get; set;}
}
Note the use of virtual properties to express the relations between the tables. As the foreign key StackImageId is supposed to be a real column, it is not virtual
In entity framework the columns of a table are represented by non-virtual properties,
the virtual properties represent the relations between the tables.
Because I followed the conventions, there is no need for attributes, nor fluent API. Entity framework detects the one-to-many collection and creates the proper tables for you. Only if you want different identifiers for your tables or columns you'll need fluent API or attributes.
I would like to create bidirectional links to the same class. Id like for the relationship class to have the attributes that would explain how the two classes are related. It may be a parent-child relationship or it be a simple "reference" relationship.
Currently, if I use the setup below, Entity Framework will automatically create a 3rd foreign key in the link table for the "myChildNodes" relationship. The only way I can get Entity Framework to understand what I am trying to do on the link class is to create two collections I.E. (childOf and ParentOf).
I would like to dynamically add relationship types and not need to create a collection representing that relationship type. I would rather handle that in the repository for the node object.
Node
{
Public int id {get; set;}
Public datetime createDate {get; set;}
Public bool isModified {get; set;}
//I would like just one collection for all links from this node as the source node
Public virtual ICollection<Link> myChildNodes{get; set;}
//I don't want to use something like this that explicitly defines the relationship
//Public virtual ICollection<Node> parentOf{get; set;}
//Public virtual ICollection<Node> childOf{get; set;}
Public Node() {
}
}
Link {
Public int id {get; set;}
Public datetime createdDate {get; set;}
Public string linkType {get; set;}
[ForeignKey("SourceNode")]
Public int? SourceNodeId { get; set;}
Public Node SourceNode {get; set;}
[ForeignKey("TargetNode")]
Public int? TargetNodeId { get; set;}
Public Node TargetNode {get; set;}
Public Link() {
}
}
Has anyone had success with this design before?
EntityFramework 5.0
Suppose I have the following setup:
public class Book
{
public int ID {get; set;}
public string Title {get; set;}
[InverseProperty("Books")]
[Required]
public Author Author {get; set;}
}
public class Author
{
public int ID {get; set;}
public string Name {get; set;}
public virtual ICollection<Book> Books {get; set;}
}
Then in my code I create a new Book and I do this:
author.Books.Add(newBook);
How can I have the Book pick-up its Author automatically instead of having to write this every time:
newBook.Author = author;
I want the child entity to pick up its parent automatically when added to the parent's collection.
Is this possible? Fluent mapping maybe?
Or do I have to maintain both sides of this bi-directional relationship myself?
My mistake.
This is the default behavior and the book gets its Author out-of-the-box.
Case closed.
I have a POCO class as follows
public class Category
{
public int ID {get; set; }
public string desc {get; set; }
public int parentID {et; set; }
}
public class Issue
{
public int ID {get; set;}
....
public int categoryID {get; set; }
public int subCategoryID {get; set; }
public virtual Category category{get; set; }
public virtual Category subCategory {get; set;}
}
I keep getting errors with foreign keys with the above classes. Basically, my Category table holds categories with sub categories. And an issue can have a category and subCategory. Would somebody guide me to the correct way to define this relationship? I've tried using Foreign Key annotations but it gives me an error saying the data base was created but the object creation failed because of foreign key relation specified on Issue. Any ideas why? And what I can do to resolve this ?
Please see this article - How to Configure a Self Referencing Entity in Code First
I believe that will help you setup the relationship correctly. As you will see in the article you need to define some addditional fluent settings in the OnModelCreating method in your DbContext class.
You can do this with a single class.
For EF4.1 Code first I have the following example:
/// <summary>
/// represents a single configuration item within CM
/// </summary>
public class CI
{
[Key]
public int ID { get; set; }
....
[ForeignKey("Parent")]
public int? Parent_ID { get; set; }
[InverseProperty("Parent")]
[ForeignKey("Parent_ID")]
public virtual ICollection<CI> Contents { get; set; }
[InverseProperty("Contents")]
public virtual CI Parent { get; set; }