Getting value of Navigation property in join - entity-framework-core

I have generated the classes from the database using scaffold.
public partial class Class1
{
public int ID { get; set; }
public int Class2ID { get; set; }
public string Name { get; set; }
public DateTime Address { get; set; }
public string City { get; set; }
public string Country { get; set; }
public virtual Class2 Class2 { get; set; }
}
public partial class Class2
{
public Class2()
{
Class1 = new HashSet<Class1>();
}
public int ID { get; set; }
public string Allotment { get; set; }
public string Manual { get; set; }
public virtual ICollection<Class1>Class1 {get; set;}
}
So there is a requirement to join these two tables in entity and get the data. And I am getting the result.
Here is my code:
var _class1Repo = UnitWork.GetGenericRepositoryFor<Class1>().AsNoTracking();
var _class2Repo = UnitWork.GetGenericRepositoryFor<Class2>().AsNoTracking();
var query = from _cls1 in _class1 in _class1Repo
join _cls2 in _class2Repo on _cls1.Class2ID = _cls2.ID
where _cls2.ID = 2
select new Class1() {
Name =_cls1 .Name,
Address =_cls1.Address,
City =_cls1 .City,
Country =_cls1.Country
// I want just only one property value inside this from class2
};
I need to include Class2 one property. How can I do that? Is there a way to achieve this?

Define your Class1.cs like this:
public class Class1
{
public int ID { get; set; }
public int Class2ID { get; set; }
public string Name { get; set; }
public DateTime Address { get; set; }
public string City { get; set; }
public string Country { get; set; }
public virtual Class2 Class2 { get; set; }
public Class1() {}
// Define this constructor
}
A constructor is a special method of the class which gets automatically invoked whenever an instance of the class is created.
So whenever you created instance you can easy to access the property.

Related

Microsoft Entity Framework Core Parent with 2 Children [duplicate]

This question already has answers here:
EF Core returns null relations until direct access
(2 answers)
Closed 4 years ago.
So I have 3 classes:
public class OwnerDto
{
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
}
public class SitterDto
{
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
}
public class ReviewDto
{
public int Id { get; set; }
public int Rating { get; set; }
//[ForeignKey("OwnerId")]
public OwnerDto Owner { get; set; }
//[ForeignKey("SitterId")]
public SitterDto Sitter { get; set; }
}
But I can't figure out how to do the proper modelBuilder. Everything I tried fails :( I am learning so bear with me.
My closest attempt was this:
modelBuilder.Entity<ReviewDto>()
.HasOne(t => t.Owner).WithMany().HasForeignKey("OwnerId");
Basically Owner and Sitter are always null :( Should i keep the [ForeignKey()] stuff or should i use a different extension method?
Declare all classes with navigation properties to each other. Mark one of the tables (the dependent table) with the ForeignKey attribute on its Primary Key.
EF infers one-to-many from this:
public class OwnerDto
{
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
public ICollection<ReviewDto> Reviewers{ get; set; }
public ICollection<SitterDto> Sitters{ get; set; }
}
public class SitterDto
{
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
public int OwnerId{ get; set; }
[ForeignKey("OwnerId")]
public OwnerDto Owner { get; set; }
}
public class ReviewDto
{
public int Id { get; set; }
public int Rating { get; set; }
public int OwnerId{ get; set; }
[ForeignKey("OwnerId")]
public OwnerDto Owner { get; set; }
}
and EF infers one-to-one from this:
public class OwnerDto
{
...
public ReviewDto Review{ get; set; }
...
}
public class ReviewDto
{
[ForeignKey("Owner")]
public int OwnerId { get; set; }
public OwnerDto Owner{ get; set; }
...
}
You need to refer Eager Loading in this scenario, You can use the Include method to specify related data to be includethe d in query results.
var query = from review in context.Review.Include(o => o.Owner).Include(s=>s.Sitter) select review;

How to build an Parent Child in EF 7

I have a table that looks like the following:
public class ServiceType
{
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
}
The Service type data has another collection of "SubTypes", which are basically a collection of ServiceType.Code. I would like to build a navigation property that references the ServiceType collection.
So I am guessing that I need to build another table to store the Id of the Parent and of the child like:
public class ServiceTypeHeirarchy
{
public int Id { get; set; }
public int ParentId { get; set; } // ServiceType.Id of Parent
public int ChildId { get; set; } // ServiceType.Id of Child
}
Not sure if I am on the right track.
It seems that you want to have many 'sub'ServiceType under one 'parent'ServiceType.
And if that is indeed the case then you can do something like following:
public class ServiceType
{
public int Id { get; set; }
public int? ParentServiceTypeId { get; set; }
public ServiceType ParentServiceType { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public ICollection<ServiceType> ChildServiceTypes { get; set; }
}
And then you might want to do an Entity Configuration with HasMany, WithOptional.

I get UpdateException when i try to Update a collection property

I am in an MVC4 application and i am using EF CodeFirst.
When I try to run the following code:
public void Autorizare(int cerereId, Persoana persoana)
{
var cerere = _db.Cereri.Find(cerereId);
cerere.Autorizare.Add(persoana);
_db.SaveChanges();
}
I get an error like this:
Entities in 'CerereDbContext.Persoane' participate in the 'Actiune_Executanti' relationship. 0 related 'Actiune_Executanti_Source' were found. 1 'Actiune_Executanti_Source' is expected.
i have tried Entity(Actiune).State = EntityState.Modified, but no results.
I have a main POCO:
public class Cerere
{
public int Id { get; set; }
...
public virtual ICollection<Actiune> Actiuni { get; set; }
...
}
the Actiune class looks like this
public class Actiune
{
public int Id { get; set; }
public DateTime Data { get; set; }
public String Nume { get; set; }
public virtual ICollection<Persoana> Executanti { get; set; }
public String Stadiu { get; set; }
public String Obs { get; set; }
}
And Persoana:
public class Persoana
{
public int Id { get; set; }
public DateTime Data { get; set; }
public String Nume { get; set; }
}
From your model the Cerere does not have a property named Autorizare; however it does have one named Actiuni. Which is of type Actiune not Persoana which is what you are trying to add to it. Please post the rest of the Class Definition.

Entity framework foreign key

I have 2 classes
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
and
public class PersonWebsite
{
public int Id { get; set; }
public string Website { get; set; }
public int PersonId{ get; set; }
}
I've seen stuff like this being done before
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public ICollection<PersonWebsite> PersonWebsites{ get; set; }
}
How could I go about implementing the code that when a Person is initialized, the PersonWebsites List will automatically be initialised and get all the PersonWebsite objects that have the same PersonId as the class that calls it.
Lazy Loading:
You can make PersonWebsites property virtual:
public virtual ICollection<PersonWebsite> PersonWebsites{ get; set; }
Entity framework will load it from the database as soon as it's required.
Also this method requires you to have lazy loading enabled which is by default:
DbContext.ContextOptions.LazyLoadingEnabled = true;
Eager Loading:
You can use include to force entity framework to load PersonWebsites on the first query:
DbSet.Include(p => p.PersonWebsites);
You may also want to change your PersonWebsite class like this, in order to navigate to the person from the PersonWebsite object (using Lazy-Loading):
public class PersonWebsite
{
public int Id { get; set; }
public string Website { get; set; }
[ForeignKey("Person")]
public int PersonId{ get; set; }
public virtual Person Person {get;set;}
}

Entity Framework 4.3 CF many - to - many relationship saving object?

When creating many to many relationship using EF 4.3 code first approach, I cannot save data to connecting table, also cannot any examples on how to fill this table using saving object to Icollection... Here is my example:
MODELS
public class Hospital
{
//PK
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string County { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public Guid User_Id { get; set; }
//FK
public virtual ICollection<Operator> Operators { get; set; }
}
public class Operator
{
//PK
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime Dob { get; set; }
public string Email { get; set; }
//FK
public virtual ICollection<Hospital> Hospitals { get; set; }
}
public class Project: DbContext
{
public DbSet<Hospital> Hospitals { get; set; }
public DbSet<Operator> Operators { get; set; }
}
CONTROLLER
public void AddOperater()
{
Hospital h = new Hospital();
h = db.Hospitals.Single(a=>a.Id ==1);
var o = new Operator();
o.FirstName = "John";
o.LastName = "Doe";
o.Dob = new DateTime(1988,2,12);
o.Email = "johndoe#gmail.com";
o.Hospitals.Add(h);
db.SaveChanges();
}
With this approach I keep getting error here: o.Hospitals.Add(h); even when my Hospital instance is filled with data. How exactly to save data to both tables, the dbo.Operators and dbo.OperatorHospital which is relationship table?
o.Hospitals.Add(h) will fail because the list is a null list. You cannot call Add() on a null list. Typically most people get around this by instantiating the list in the constructor of the entity... like so... the current line is blowing up due to a CSharp issue.
public class Hospital
{
//PK
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string County { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public Guid User_Id { get; set; }
//FK
public virtual ICollection<Operator> Operators { get; set; }
public Hospital()
{
Operators = new List<Operator>();
}
}
public class Operator
{
//PK
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime Dob { get; set; }
public string Email { get; set; }
//FK
public virtual ICollection<Hospital> Hospitals { get; set; }
public Operator()
{
Hospitals = new List<Hospital>();
}
}