ef6 query many to many using bridge - linq

how do I query this many to many relationship? I am starting with ACCOUNT, and want to return the ExecutingBroker.Firm associated with it.
I am starting with Account, then I guess drill to MANAGER, then to MAPPING_MANAGER, then to EXECUTINGBROKER.
Here is my query so far...
var student = dbEF.Accounts
.Where(x => x.AccountNumber == acctNum)
.Select(x => new DTOCrmDetails()
{
AccountNumber = x.AccountNumber,
AccountName = x.AccountName,
DateOpened = x.DateOpened,
CommissionId = x.CommissionId,
Commission = x.Commission,
ManagerID = x.ManagerID,
ManagerName = x.Manager.ManagerName,
Manager = x.Manager,
Employees = x.Manager.Employees,
WireInstructionsUSD = x.Manager.WireInstructionsUSDs
}).FirstOrDefault();
below is the code that was generated from ef from existing database.
public partial class Manager
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Manager()
{
this.Accounts = new HashSet<Account>();
this.Employees = new HashSet<Employee>();
this.WireInstructionsUSDs = new HashSet<WireInstructionsUSD>();
this.Mapping_ManagersExecutingBrokers = new HashSet<Mapping_ManagersExecutingBrokers>();
}
public int ManagerID { get; set; }
public string ManagerName { get; set; }
public string Strategy { get; set; }
public string ManagerShortCode { get; set; }
public Nullable<int> WireInstructionsUsdID { get; set; }
public Nullable<int> WireInstructionsForeignID { get; set; }
public string MEtradingPlatform { get; set; }
public string EtradingCostResp { get; set; }
public string NotesManager { get; set; }
public bool MainStrategy { get; set; }
public string PathPayments { get; set; }
public string PathEtrading { get; set; }
public string LEI { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Account> Accounts { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Employee> Employees { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<WireInstructionsUSD> WireInstructionsUSDs { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Mapping_ManagersExecutingBrokers> Mapping_ManagersExecutingBrokers { get; set; }
}
}
{
using System;
using System.Collections.Generic;
public partial class Mapping_ManagersExecutingBrokers
{
public int Mapping_ManagersExecutingBrokersId { get; set; }
public Nullable<int> ManagerID { get; set; }
public Nullable<int> ExecutingBrokersId { get; set; }
public virtual ExecutingBroker ExecutingBroker { get; set; }
public virtual Manager Manager { get; set; }
}
}
public partial class ExecutingBroker
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public ExecutingBroker()
{
this.Mapping_ManagersExecutingBrokers = new HashSet<Mapping_ManagersExecutingBrokers>();
}
public int ExecutingBrokersId { get; set; }
public string Firm { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Mapping_ManagersExecutingBrokers> Mapping_ManagersExecutingBrokers { get; set; }
}

You have to go through Mapping_ManagersExecutingBrokers, since you've modelled it that way.
Keep in mind that you have a collection of Firms, since it's a many-to-many-relationship.
.Select(account => new { Firms = account.Manager.Mapping_ManagersExecutingBrokers
.Select(meb => meb.ExecutingBroker.Firm) });

Related

AbpBoilerPlate EF Core 3.0 StackOverflowException during UpdateAsync

Recently I've experienced this error while trying to update entities in MS SQL Database.
I have two models:
[AutoMap(typeof(Employees))]
[Table("Employees")]
public class Employees : FullAuditedEntity
{
public Employees()
{
EmployeesAdresses = new HashSet<EmployeesAdresses>();
WorkTimeEntries = new HashSet<WorkTimeEntries>();
ContractEntries = new HashSet<ContractEntries>();
}
public string Name { get; set; }
public string Surname { get; set; }
public string Description { get; set; }
public bool IsActive { get; set; }
public ICollection<EmployeesAdresses> EmployeesAdresses { get; set; }
public ICollection<WorkTimeEntries> WorkTimeEntries { get; set; }
public ICollection<ContractEntries> ContractEntries { get; set; }
[NotMapped]
public List<GroupRelations> GroupRelations { get; set; }
}
[AutoMap(typeof(EmployeesAdresses))]
[Table("EmployeesAdresses")]
public class EmployeesAdresses : FullAuditedEntity
{
public string Street { get; set; }
public string HouseNumber { get; set; }
public string ApartmentNumber { get; set; }
public string PostalCode { get; set; }
public string City { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public bool IsDefault { get; set; }
public bool IsActive { get; set; }
[ForeignKey("Employees")]
public int EmployeeId { get; set; }
public virtual Employees Employee { get; set; }
}
I am trying to update Employee Adress using simple appservice:
public async Task UpdateEmployee (Employees employeeInput)
{
try
{
var _employee = await _employeesRepository.GetAllIncluding(x => x.EmployeesAdresses).Where(x => x.Id == employeeInput.Id).SingleOrDefaultAsync();
if (_employee == null)
throw new Exception($"Brak pracownika o ID: {employeeInput.Id}");
_employee.EmployeesAdresses.Clear();
_employee.WorkTimeEntries.Clear();
ObjectMapper.Map(employeeInput, _employee);
await _employeesRepository.UpdateAsync(_employee);
}
catch (Exception ex)
{
throw new UserFriendlyException(#"Wystąpił błąd podczas aktualizacji pracownika.", ex.Message, ex.InnerException);
}
}
I am getting StackOverFlowException and I really don't know whats the issue. Last error on stacktrace in diagnostic tool event tab is StringCompare error.
Did you experience such a behaviour? Any ideas what might be a problem?

Why is Entity Framework navigation property null?

I am use code first model with a relationship below
public class ApplicationUser : IdentityUser
{
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
public string UserSchool { get; set; }
public UserProfileData UserProfileData { get; set; }
public int? MedicalSpecialtyId { get; set; }
public virtual MedicalSpecialty MedicalSpecialty { get; set; }
// public int? AnalyticsDataId { get; set; }
// public ICollection<AnalyticsData> AnalyticsDatas { get; set; }
}
public class MedicalSpecialty
{
public int Id { get; set; }
public string Description { get; set; }
// public int ApplicationUserId { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
public ICollection<ProgramDetailData> ProgramDetailDatas { get; set; }
}
And when I try to get a User's associated MedicalSpecialty object it is NULL
userSpecialtyName = currentUser.MedicalSpecialty.Description;
BUT when I run this code above it the currentUser.MedicalSpecialty is no longer NULL. What happened?? Somehow that LINQ query woke up the object and filled it with data
var userSpecialtyId = currentUser.MedicalSpecialtyId;
userSpecialtyName = _medicalSpecialtyRepository.Find
(x => x.Id == userSpecialtyId).FirstOrDefault().Description;
userSpecialtyName = currentUser.MedicalSpecialty.Description;

Querying Many to Many relationship table to entities MVC

I have many to many relationship tables. Sube and User
namespace Odev.Entities
{
public class User
{
[Key]
public int Id { get; set; }
[Required]
[DisplayName("Kimlik No")]
[ StringLength(11)]
[Index(IsUnique = true)]
public string UserName { get; set; }
[ StringLength(8)]
[DisplayName("Şifre")]
public string Password { get; set; }
[DisplayName("Ad Soyad")]
public string NameSurname { get; set; }
[DisplayName("Bölüm")]
public string Bolum { get; set; }
[DisplayName("Dal")]
public string Dal { get; set; }
[DisplayName("Öğrenci No")]
public int OgrenciNo { get; set; }
public int RoleId { get; set; }
public virtual ICollection<Sube> Subes { get; set; }
public virtual List<Notification> Notifications { get; set; }
public virtual List<Homework> Homeworks { get; set; }
public virtual Role Role { get; set; }
}
}
namespace Odev.Entities
{
public class Sube
{
[Key]
public int Id { get; set; }
[DisplayName("Şube")]
public string Sube_Name { get; set; }
public virtual Homework Homework { get; set; }
public virtual ICollection<User> Users { get; set; }
}
}
namespace Odev.DataAccessLayer
{
public class DatabaseContext : DbContext
{
public DatabaseContext() : base("dataConnection")
{
Database.SetInitializer(new OdevInitializer());
}
public DbSet<User> Users { get; set; }
public DbSet<Homework> Homeworks { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<Sube> Subes { get; set; }
public DbSet<Notification> Notifications { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}
and my ViewModel
namespace Odev.Models{
public class ViewModel{
public string Sube_Name { get; set; }
public string NameSurname { get; set; }
public string UserName { get; set; }
public int UserId { get; set; }
public int SubeId { get; set; }
public User User { get; set; }
public Sube Sube { get; set; }
public Role Role { get; set; }
}}
I want to show User's SubeId:
How I select Sube's id ?
You need connect both entities with a foreign key.
Please, read this doc: Creating a More Complex Data Model for an ASP.NET MVC Application

How to perform a LINQ join on IQueryable action in odata controller

I have a WebAPI method which uses the OData Query Options to return data to the client. The entity has cityid and I want cityname from another entity using joins.
I have tried using below Api method, which in turn evaluate the joins but not returning it in result.
Entity1:-
public partial class UU_DeliveryCharges
{
public int DeliveryChargeId { get; set; }
public Nullable<int> CityId { get; set; }
public Nullable<int> VehicleTypeId { get; set; }
public Nullable<decimal> MileRate { get; set; }
public Nullable<decimal> FlatRate { get; set; }
public Nullable<decimal> FlatMile { get; set; }
public Nullable<decimal> PickUpFee { get; set; }
public Nullable<decimal> DropOffFee { get; set; }
public Nullable<int> CreateBy { get; set; }
public Nullable<System.DateTime> SysDate { get; set; }
public Nullable<bool> Status { get; set; }
}
Entity2:-
public partial class SC_Cities
{
public int CityId { get; set; }
public Nullable<int> StateId { get; set; }
public string CityName { get; set; }
public Nullable<bool> CityStatus { get; set; }
}
Class:-
public partial class DeliveryCharges
{
public string ReturnCode { get; set; } //-1:Error/0:missing or validation /1:success
public string ReturnMessage { get; set; }
public string CountryName { get; set; }
public string StateName { get; set; }
public string CityName { get; set; }
public string VehicleName { get; set; }
public Nullable<decimal> MileRate { get; set; }
public Nullable<decimal> FlatRate { get; set; }
public Nullable<decimal> FlatMile { get; set; }
public Nullable<decimal> PickUpFee { get; set; }
public Nullable<decimal> DropOffFee { get; set; }
}
WebApi Method:-
public IQueryable<DeliveryCharges> GetUU_DeliveryCharges()
{
//var aaa= db.UU_DeliveryCharges;
//return aaa;
var results = from deliveries in db.UU_DeliveryCharges
join vehicles in db.UU_VehicleTypes on deliveries.VehicleTypeId equals vehicles.VehicleTypeId
join cities in db.SC_Cities on deliveries.CityId equals cities.CityId
join states in db.SC_States on cities.StateId equals states.StateId
join countries in db.SC_Countries on states.CountryId equals countries.CountryId
where (deliveries.Status == true)
select new DeliveryCharges
{
FlatRate = deliveries.FlatRate,
MileRate = deliveries.MileRate,
PickUpFee = deliveries.PickUpFee,
DropOffFee = deliveries.DropOffFee,
CityName = cities.CityName
//UU_DeliveryCharges = deliveries.FlatMile, deliveries.MileRate, deliveries.PickUpFee, deliveries.DropOffFee
//,vehicles = vehicles.VehicleType, cities = cities.CityName, states = states.StateName, countries = countries.CountryName
};
return results;
}
WebAPIConfig:-
public static void Register(HttpConfiguration config)
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<UU_DeliveryCharges>("UU_DeliveryCharges");
config.Routes.MapODataRoute("odata", "odata", builder.GetEdmModel());
}

Entity Framework also Linq advice needed

i have got on my DB 3 tables
movies, workers, workermovies ( this is the Relationship table )
public class Movie
{
public Movie()
{
Genres = new List<Genre>();
Formats = new List<Format>();
ProductionCompanies = new List<ProductionCompany>();
Workers = new List<Worker>();
}
public int Id { get; set; }
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
public string StoryLine { get; set; }
public int RunTime { get; set; }
[ForeignKey("MPAARateId")]
public MPAARate MPAARate { get; set; }
public int MPAARateId { get; set; }
public byte[] ImageData { get; set; }
public string ImageMimeType { get; set; }
public DateTime CreatedDate { get; set; }
public string OfficialSite { get; set; }
public int Budget { get; set; }
public int StatusId { get; set; }
public virtual ICollection<Genre> Genres { get; set; }
public virtual ICollection<Format> Formats { get; set; }
public virtual ICollection<ProductionCompany> ProductionCompanies { get; set; }
public virtual ICollection<Worker> Workers { get; set; }
}
public class Worker
{
public int Id { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public DateTime Birthday { get; set; }
public string Biography { get; set; }
public string BornName { get; set; }
public double Height { get; set; }
public DateTime? Died { get; set; }
public byte[] ImageData { get; set; }
public string ImageMimeType { get; set; }
public bool IsActor { get; set; }
public bool IsDirector { get; set; }
public bool IsWriter { get; set; }
public bool IsProducer { get; set; }
public bool IsStar { get; set; }
public virtual ICollection<Movie> Movies { get; set; }
}
in this Relation i got the movieId and the workerId
but i also got some more fields if the person acted or writen or producer etc.
how do i define the relation entity class if needed
and when i want to get just the ppl that acted in the movie how do i wrote such a linq
query
You need to introduce an additional entity in your model WorkerMovie and convert the many-to-many relationship between Worker and Movie into two one-to-many relationships - one between Worker and WorkerMovie and the other between Movie and WorkerMovie. A sketch:
public class WorkerMovie
{
[Key, Column(Order = 0)]
public int WorkerId { get; set; }
[Key, Column(Order = 1)]
public int MovieId { get; set; }
public Worker Worker { get; set; }
public Movie Movie { get; set; }
public bool WorkedAsActor { get; set; }
public bool WorkedAsWriter { get; set; }
public bool WorkedAsProducer { get; set; }
// etc.
}
public class Movie
{
// ...
public virtual ICollection<WorkerMovie> WorkerMovies { get; set; }
// remove ICollection<Worker> Workers
}
public class Worker
{
// ...
public virtual ICollection<WorkerMovie> WorkerMovies { get; set; }
// remove ICollection<Movie> Movies
}
If you want only to find the workers who were actors in a particular movie with a movieId you can write:
var workersAsActors = context.WorkerMovies
.Where(wm => wm.MovieId == movieId && wm.WorkedAsActor)
.Select(wm => wm.Worker)
.ToList();
Here is another answer to a very similar question with many more examples of possible queries: Create code first, many to many, with additional fields in association table

Resources