For example I have these three tables . The second 2 tables have firstID as its foreign key. However I did not explicitely set this relation using entity framework and thought I'll handle it in the BLL. Is there a simple way I can get all the data from all 3 tables using the firstID ? . I know i can join using sql query but thinking of a easier approach.
Note: the Second and third table can have many records with the same FirstId. So I am using a list to construct my FirstTable object
FirstTable
public int firstID {get;set;}
public string name {get;set;}
public List<SecondTable> second {get; set;}
public List<ThirdTable> third {get; set;}
SecondTable
public int secondID {get;set;}
public int number {get;set;}
public int firstID {get;set;}
ThirdTable
public int thirdID {get;set;}
public int age {get;set;}
public int firstID {get;set;}
Related
I am using entity framework core 5 query syntax. There are 3 classes which reflect the tables in database.
public class Record { public int RecordID {get; set;} public decimal Amount {get; set} public string AccountName {get; set;} }
public class Dimension { public int DimensionID {get; set;} public string DimensionSymbol {get; set;} }
public class DimensionName { public int ID {get; set;} public string Name {get; set;} }
public class RecordDto { public int ID {get; set;} public string DimensionName {get; set;} }
The aim is to find DimensionName foreach Record. The relationship is as follows. RecordID field is a foreign key for Dimension. So it is easy to find this relationship. The problem is with DimensionName. DimensionID is NOT a foreign key to DimensionName. The logical key is DimensionSymbol which sometimes is a simple text like "200.000B" and sometimes it represents the number like 190. If DimensionSymbol is 190 then this 190 reflects the ID in DimensionName.
My query is as follows.
var query = from r in context.Records
join d in context.Dimensions on r.RecordID equals d.DimensionID
join n in context.DimensionNames on int.Parse(d.DimensionSymbol)\>0 ? int.Parse(d.DimensionSymbol) : 0 equals n.ID
select new RecordDto
{
ID = r.RecordID,
DimensionName = n.Name
}
And it doesn't work. Could you please adjust the code so that it works? Maybe I should configure sth in OnConfiguring method.
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;}
}
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?
I'm using EF Code first.
I created two classes. For simplicity, imagine that I have a User table (class) and a FileAttachment table. I want to use the FileAttachment table with many other classes, so that any part of the application that requires having a FileAttachment can reuse that table. The problem is that when EF generates the schema, it creates a Foreign Key in the FileAttachment table back to User table. Is there a way to disable that?
Thanks
You need to build an intermediate class.
public class UserDocument
{
public int Id {get;set;}
public int UserId {get;set;}
public virtual User User {get;set;}
public int FileAttachmentId {get;set;}
public virtual FileAttachment FileAttachment {get;set;}
}
So your user class can now have:
public virtual ICollection<UserDocument> Documents {get;set;}
And in this case, FileAttachment class will not have reference to User.
If you want now to build some other document type, just implement another intermediate type, i.e. imagine you want to have CustomerDocument:
public class CustomerDocument
{
public int Id {get;set;}
public int CustomerId {get;set;}
public virtual Customer Customer {get;set;}
public int FileAttachmentId {get;set;}
public virtual FileAttachment FileAttachment {get;set;}
}
And then your hypothetical Customer class would have:
public virtual ICollection<CustomerDocument> Documents {get;set;}
I am doing a Code-first EF approach except for the fact that I am managing the database (for schema change issues that I believe still exist in code-first). I have the following tables / model objects (eliding several parameters, etc) :
class A {
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public virtual List<B> BList {get;set;}
public virtual List<C> CList {get;set;}
}
class B {
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[ForeignKey("A"), Required]
public int AId {get; set;}
public virtual A parent {get;set;}
public virtual List<D> DList {get;set;}
}
class C {
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[ForeignKey("A"), Required]
public int AId {get;set;}
[ForeignKey("someD"), Required]
public int someDId {get;set}
public virtual D someD
}
class D {
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[ForeignKey("B"), Required]
public int BId {get;set;}
public string data {get;set;}
}
There's more to it than that, but the idea is that from a parent object A, I can navigate to a D along two different relationships. The Cascade delete relationships in the database are set up such that A->B, A->C, and B->D are cascades; C->D is 'no action'.
Therefore, when I go to delete an A (DbSet.Remove(a); SaveChanges(); etc ) EF needs to delete the C branch first, so that it can later delete the D's and not violate the FK constraint C->D. However, it appears to be choosing the other path, as the delete throws an exception about said constraint being violated. Is there a way for me to provide a hint (attribute or otherwise) to EF to tell it something else about these relationships so it can delete things in the right order?
edit Added more clarity to the approach in the code; Also, this thought occurs to me: I'm not explicitly capturing the relationship from C->D on D's end - that is, there is no navigation property on D that points to C; because C is a part of a Table-per-type scheme and not all D's point to a good collection of C's base class. Do I need to have some kind of navigation property in D back to C for EF to understand what I want?