multiple navigation properties to the same table using code first - c#

I have a one-to-many relationship setup. IT is working fine but now I am trying to use pdfsharp and I need some help with the navigation properties. Every Measurement has 4 pictures. Front, Back, Right, Left. I need to include all 4 pics in the pdf. I am unable to reach them with what i have now. I can return the list of pictures per measurement in a table. Just dont know how to change it for this to work as well.
public class Measurement
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
public DateTime? MeasurementDate { get; set; }
public decimal? BustMeasurement { get; set; }
public decimal? ChestMeasurement { get; set; }
public decimal? FAT { get; set; }
public string MeasurementUploadBy { get; set; }
public DateTime? MeasurementUploadDate { get; set; }
public DateTime? MeasurementEditDate { get; set; }
public string MeasurementEditBy { get; set; }
public int? ClientId { get; set; }
[ForeignKey("ClientId")]
public virtual Client Client { get; set; }
public virtual ICollection<Picture> Pictures { get; set; }
}
public class Picture
{
public int Id { get; set; }
public string PictureFrontUrl { get; set; }
public string PictureBackUrl { get; set; }
public string PictureRightSideUrl { get; set; }
public string PictureLeftSideUrl { get; set; }
public string PictureNote { get; set; }
public string PictureUploadBy { get; set; }
public DateTime? PictureUploadDate { get; set; }
public DateTime? PictureDate { get; set; }
public string ClientName { get; set; }
public string PictureType { get; set; }
public Guid MeasurementId { get; set; }
[ForeignKey("MeasurementId")]
public virtual Measurement Measurement { get; set; }
}
MeasurementApi
public Measurement GetMeasurement(Guid id)
{
using (var context = new ApplicationDbContext())
{
Measurement model = new Measurement();
model = context.Measurements
.Include(x => x.Pictures)
.FirstOrDefault(j => j.Id == id);
return model;
}
}
PDFSharp GEt Call
apiMeasurementController adapter = new apiMeasurementController();
Measurement model = new Measurement();
model = adapter.GetMeasurement(id);

If you want your Measurement to have 4 pictures, and not a colleciton of pictures you should have something like this:
public class Measurement
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
....
// Won't need these
// public virtual ICollection<Picture> Pictures { get; set; }
public virtual Picture LeftPicture { get; set; }
public virtual Picture TopPicture { get; set; }
public virtual Picture RightPicture { get; set; }
public virtual Picture BottomPicture { get; set; }
}
And your picture:
public class Picture
{
public int Id { get; set; }
// Don't need these 4 any more.
// public string PictureFrontUrl { get; set; }
// public string PictureBackUrl { get; set; }
// public string PictureRightSideUrl { get; set; }
// public string PictureLeftSideUrl { get; set; }
public string PictureUrl { get; set; }
public string PictureNote { get; set; }
public string PictureUploadBy { get; set; }
public DateTime? PictureUploadDate { get; set; }
public DateTime? PictureDate { get; set; }
public string ClientName { get; set; }
public string PictureType { get; set; }
public Guid MeasurementId { get; set; }
[ForeignKey("MeasurementId")]
public virtual Measurement Measurement { get; set; }
}
And in your API
public Measurement GetMeasurement(Guid id)
{
using (var context = new ApplicationDbContext())
{
Measurement model = new Measurement();
model = context.Measurements
.Include(x => x.LeftPicture)
.Include(x => x.TopPicture)
.Include(x => x.RightPicture)
.Include(x => x.BottomPicture)
.FirstOrDefault(j => j.Id == id);
return model;
}
}

Related

Get All data from two tables in .net 5 web api?

Patient.cs //This is Patient Model Class
namespace HMS.Models
{
public class Patient
{
[Key]
public string Id { get; set; }
public string Name { get; set; }
public int age { get; set; }
public int Weight { get; set; }
public string Gender { get; set; }
public string Address { get; set; }
public string PhoneNo { get; set; }
public string Disease { get; set; }
[JsonIgnore]
public IList<DoctorPatient> DoctorPatients { get; set; }
public InPatient InPatients { get; set; }
public OutPatient OutPatients { get; set; }
}
}
InPatient.cs //This InPatient Model Class
namespace HMS.Models
{
public class InPatient
{
[ForeignKey("Patient")]
public string InPatientId { get; set; }
public string RoomNo { get; set; }
public DateTime DateOfAddmission { get; set; }
public DateTime DateOfDischarge { get; set; }
public int Advance { get; set; }
public string LabNo { get; set; }
public Patient Patient { get; set; }
}
}
Here Patient and InPatient Attribute have one-to-one relationship
ViewInPatient.cs
namespace HMS.Models
{
public class ViewInPatient
{
public string Name { get; set; }
public int age { get; set; }
public int Weight { get; set; }
public string Gender { get; set; }
public string Address { get; set; }
public string PhoneNo { get; set; }
public string Disease { get; set; }
public string RoomNo { get; set; }
public DateTime DateOfAddmission { get; set; }
public DateTime DateOfDischarge { get; set; }
public int Advance { get; set; }
public string LabNo { get; set; }
}
}
Here is my DbContext class
public class ApplicationDbContext:DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options):base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<DoctorPatient>()
.HasOne(x => x.Doctor)
.WithMany(dp => dp.DoctorPatients)
.HasForeignKey(di => di.DoctorId);
modelBuilder.Entity<DoctorPatient>()
.HasOne(y => y.Patient)
.WithMany(dp => dp.DoctorPatients)
.HasForeignKey(pi => pi.PatientId);
}
public DbSet<Patient> Patients { get; set; }
public DbSet<Doctor> Doctors { get; set; }
public DbSet<DoctorPatient> DoctorPatients { get; set; }
public DbSet<InPatient> InPatients { get; set; }
//public DbQuery<ViewInPatient> ViewInPatients { get; set; }
}
How to get all data of both Patients and InPatients Table like in ViewInPatient class? (I tried to create a view in sql server but in add table window it shows InPatient instead of InPatients and it return null value)
You can join both models in a Linq expression and return ViewInPatient list:
var ViewInPatient_set =
YourContext
.InPatients
.Select(i=> new ViewInPatient()
{
Name = i.Patient.Name,
// ...
RoomNo = i.RoomNo,
// ...
}
)
.ToList(); // <-- transform to list is optional

Edit with viewmodel in entity frameworkcore

Hello I have a problem is that I cannot edit my model using a viewmodel and I tried to integrate the automapping but it did not work because in my viewmodel I have models at the Palce of properties I would like to know is if there is another simpler solution to make it work
error : System.InvalidOperationException : 'The instance of entity type 'SeDevisTest' cannot be tracked because another instance with the same key value for {'DevisId'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.'
thank you
this is my Controller
public ActionResult edit(ViewModelEtudes viewModelEtudes)
{
ViewModelEtudes Etudes = new ViewModelEtudes();
serviceEtudesEnCours.remplirDrowdownliste(demId);
var resultDevis= _context.SeDevisTest.FirstOrDefault(item => item.DevisFkDemNum == demId);
if (resultDevis != null)
{
_context.Entry(viewModelEtudes.SeDevisTest).State = EntityState.Modified;
_context.SaveChanges();
}
return View(Etudes);
}
this is my view model it contains the entity that I will change se_devis
public class ViewModelEtudes
{
public SeDevisTest SeDevisTest { get; set; }
public SeDemande seDemandes { get; set; }
public SeInformationRecrutement InformationRecrutement { get; set; }
public SeControleProduit controleProduit { get; set; }
public SeQuestionnaire questionnaire { get; set; }
public SePersonnelSyres SePersonnelSyres { get; set; }
public SeTypeProduit SeTypeProduit { get; set; }
public List<SeCritereTest> SeCritereTest { get; set; }
public SePartenir sePartenirs { get; set; }
public SeTraitementDemande seTraitementDemandes { get; set; }
public SeInformationClient SeInformationClient { get; set; }
public SeClient SeInclient { get; set; }
public SeAssistantClient assitantclient { get; set; }
public SeReceptionProduit receptionProduit { get; set; }
public SePrestation prestation { get; set; }
public SeRapport seRapport { get; set; }
public SeResultat seResultat { get; set; }
public SeDemandeTypeProduit demandeTypeProduit { get; set; }
}
this is my Entity SE_DEVIS_TEST
public SeDevisTest()
{
Correspondance = new HashSet<Correspondance>();
SeCorrecponsance = new HashSet<SeCorrecponsance>();
SeFacture = new HashSet<SeFacture>();
SePlainte = new HashSet<SePlainte>();
SeQuestionnaire = new HashSet<SeQuestionnaire>();
SeRapport = new HashSet<SeRapport>();
}
public int DevisId { get; set; }
public DateTime? DevisDateCreation { get; set; }
public DateTime? DevisDateEnvoi { get; set; }
public bool? DevisAnnulation { get; set; }
public DateTime? DevisDateAnnulation { get; set; }
public int? DevisMotifAnnulationDesc { get; set; }
public bool? DevisConserverFacturation { get; set; }
public bool? DevisSigneReçu { get; set; }
public DateTime? DevisDateReception { get; set; }
public bool? DevisAttestationReçu { get; set; }
public DateTime? DevisDateReceptionAttestation { get; set; }
public string DevisConditionParticuliere { get; set; }
public int? DevisFkDemNum { get; set; }
public int? DevisFkSatisfaClientId { get; set; }
public int? DevisDiffcultéEstimé { get; set; }
public string DevisSy { get; set; }
public int? DevisNbRapport { get; set; }
public virtual SeQualiDifficulte DevisDiffcultéEstiméNavigation { get; set; }
public virtual SeTraitementDemande DevisFkDemNumNavigation { get; set; }
public virtual SeSatisfactionClient DevisFkSatisfaClient { get; set; }
public virtual SeColisage SeColisage { get; set; }
public virtual SeGestionBase SeGestionBase { get; set; }
public virtual SeInformationRecrutement SeInformationRecrutement { get; set; }
public virtual SeLettre SeLettre { get; set; }
public virtual SeOrganistationRecrutement SeOrganistationRecrutement { get; set; }
public virtual ICollection<Correspondance> Correspondance { get; set; }
public virtual ICollection<SeCorrecponsance> SeCorrecponsance { get; set; }
public virtual ICollection<SeFacture> SeFacture { get; set; }
public virtual ICollection<SePlainte> SePlainte { get; set; }
public virtual ICollection<SeQuestionnaire> SeQuestionnaire { get; set; }
public virtual ICollection<SeRapport> SeRapport { get; set; }
}

Including foreign key values into a DTO for a single record

It's been a while since I have done this, but I know there is an easy way to do this that I have forgotten. Below I have a class designed to populate a single record of a data object. But I cannot get the values from another table (related by foreign key) to populate using the lambda statement because I am missing something (the two values being pulled in from another table below can be seen as dto.LeaseName and dto.CarName). How should I write the lambda for the object dm?
public StationUnloadingLogDTO GetSingleRecordforLog(int Id)
{
StationUnloadingLogDTO dto = new StationUnloadingLogDTO();
StationUnloadingLog dm = new StationUnloadingLog();
dm = entity.StationUnloadingLog
.Where(x => x.Id == Id)
.FirstOrDefault();
dto.Id = dm.Id;
dto.DateLogged = dm.DateLogged;
dto.DriverName = dm.DriverName;
dto.TruckNumber = dm.TruckNumber;
dto.CarName = dm.Carrier.CarName;
dto.CarrierId = dm.CarrierId;
dto.SpecificGravity = dm.SpecificGravity;
dto.LactMeterOpen = dm.LactMeterOpen;
dto.LactMeterClose = dm.LactMeterClose;
dto.EstimatedBarrels = dm.EstimatedBarrels;
dto.TicketNumber = dm.TicketNumber;
dto.LeaseNumber = dm.LeaseNumber;
dto.LeaseName = dm.Company.CmpName;
dto.StationId = dm.StationId;
return dto;
}
Here are the related data classes
namespace Data.Models
{
public partial class Company
{
public Company()
{
StationUnloadingLog = new HashSet<StationUnloadingLog>();
}
public string CmpId { get; set; }
public string CmpName { get; set; }
public string CmpAddress1 { get; set; }
public string CmpAddress2 { get; set; }
public int? CmpCity { get; set; }
public string CmpZip { get; set; }
public string CmpPrimaryphone { get; set; }
public ICollection<StationUnloadingLog> StationUnloadingLog { get; set; }
}
public class StationUnloadingLogDTO
{
public int Id { get; set; }
public DateTime? DateLogged { get; set; }
public string DriverName { get; set; }
public string TruckNumber { get; set; }
public string CarrierId { get; set; }
public string CarName { get; set; }
public decimal? SpecificGravity { get; set; }
public decimal? LactMeterOpen { get; set; }
public decimal? LactMeterClose { get; set; }
public int? EstimatedBarrels { get; set; }
public string TicketNumber { get; set; }
public string LeaseName { get; set; }
public string LeaseNumber { get; set; }
public string StationId { get; set; }
}
public partial class StationUnloadingLog
{
public int Id { get; set; }
public DateTime? DateLogged { get; set; }
public string DriverName { get; set; }
public string TruckNumber { get; set; }
public string CarrierId { get; set; }
public decimal? SpecificGravity { get; set; }
public decimal? LactMeterOpen { get; set; }
public decimal? LactMeterClose { get; set; }
public int? EstimatedBarrels { get; set; }
public string TicketNumber { get; set; }
public string LeaseNumber { get; set; }
public string StationId { get; set; }
public Carrier Carrier { get; set; }
public Company Company { get; set; }
public Tractorprofile Tractorprofile { get; set; }
}
public partial class Carrier
{
public Carrier()
{
StationUnloadingLog = new HashSet<StationUnloadingLog>();
}
public string CarId { get; set; }
public string CarName { get; set; }
public string CarAddress1 { get; set; }
public string CarAddress2 { get; set; }
public int? CtyCode { get; set; }
public string CarZip { get; set; }
public string CarContact { get; set; }
public ICollection<StationUnloadingLog> StationUnloadingLog { get; set; }
}
You should query for your record with child entities like this.
dm = DbSet<StationUnloadingLog>
.Where(x => x.Id == Id).Include(x => x.Carrrier)
.FirstOrDefault();

Entity Framework creates a new record per foreign key in another table while seeding

I'm trying to seed a database using EF.
I have a table that holds products (phones) and a Category table that differentiates between different types of products.
public class Category
{
public int CategoryId { get; set; }
public string Name { get; set; }
public DateTimeOffset? CreationDate { get; set; }
public DateTimeOffset? UpdateDate { get; set; }
public virtual List<IProduct> Products{ get; set; }
public Category()
{
this.CreationDate = DateTimeOffset.UtcNow;
}
}
public interface IProduct
{
int ProductId { get; set; }
string Brand { get; set; }
string Model { get; set; }
decimal? Price { get; set; }
string Image { get; set; }
int CategoryId { get; set; }
Category Category { get; set; }
}
public class Phone: IProduct
{
public int ProductId { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
public string Brand { get; set; }
public string Model { get; set; }
public string network_technology { get; set; }
public string bands_2G { get;set; }
public string bands_3G{ get; set; }
public string bands_4G { get; set; }
public string network_speed { get; set; }
public string GPRS { get; set; }
public string EDGE { get; set; }
public string announced { get; set; }
public string status { get; set; }
public string dimentions { get; set; }
public float? weight_g { get; set; }
public float? weight_oz { get; set; }
public string SIM { get; set; }
public string display_type { get; set; }
public string display_resolution { get; set; }
public string display_size { get; set; }
public string OS { get; set; }
public string CPU { get; set; }
public string Chipset { get; set; }
public string GPU { get; set; }
public string memory_card { get; set; }
public string internal_memory { get; set; }
public string RAM { get; set; }
public string primary_camera { get; set; }
public string secondary_camera { get; set; }
public string loud_speaker { get; set; }
public string audio_jack { get; set; }
public string WLAN { get; set; }
public string bluetooth { get; set; }
public string GPS { get; set; }
public string NFC { get; set; }
public string radio { get; set; }
public string USB { get; set; }
public string sensors { get; set; }
public string battery { get; set; }
public string colors { get; set; }
public decimal? Price { get; set; }
public string Image { get; set; }
}
I don't know what am I doing wrong but after I update the database from nuget console, a new Category record is created per seeded product(phone). That's exactly the opposite of what I want. I want all the phones to have one categoryId that refers to Phones category. does anyone know what's wrong?
Entity Type Configurations (fluent api):
public class CategoryConfiguration : EntityTypeConfiguration<Category>
{
public CategoryConfiguration()
{
ToTable("Categories");
HasKey(m => m.CategoryId);
}
}
public class PhoneConfiguration : EntityTypeConfiguration<Phone>
{
public PhoneConfiguration()
{
ToTable("Phones");
HasKey(m => m.ProductId);
}
}
Seed method:
protected override void Seed(BestPhone.Data.BestPhoneDbContext context)
{
context.Categories.AddOrUpdate(new Category(){Name = "Phones", CategoryId = 1});
...
//getting records from a csv file and holding them in an array.
var records = csvReader.GetRecords<Phone>().ToArray();
foreach (var record in records)
{
record.CategoryId = 1;
}
context.Phones.AddRange(records);
context.SaveChanges();
}
}
Try to add the next method on your CategoryConfiguration class:
public void Configure(EntityTypeBuilder<Category> builder)
{
builder
.HasMany(s => s.Products)
.WithOne(t => t.Category)
.HasForeignKey(t => t.CategoryId);
}
I'm not sure but it seems a system does not take into account your foreign key during seeding.

C# Entity Framework - Multiple relationships

I'm not sure if this is possible or not, but I thought I would ask...
I have two database tables. One is a list of users pulled from Active Directory. The second table is a list of scheduled forwards. The relationship I would like to create would be...
public class AdObject
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string ObjectType { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string DisplayName { get; set; }
public string DistinguishedName { get; set; }
public string PrimaryEmail { get; set; }
public string Alias { get; set; }
public string SamAccountName { get; set; }
public string PrimaryDisplay { get; set; }
public string CanonicalName { get; set; }
public string OU { get; set; }
public string CoreGroup { get; set; }
public string ForwardedTo { get; set; }
public bool? IsDisabled { get; set; }
public bool? IsForwarded { get; set; }
public bool? DeliverAndRedirect { get; set; }
public bool? DisableForwardAtLogon { get; set; }
public DateTime? DisableAtLogonAfter { get; set; }
public string Notify { get; set; }
public DateTime? LastLogon { get; set; }
public DateTime? LastApiLogon { get; set; }
public DateTime? LastCheck { get; set; }
// This isn't required. But if possible I would like this to be
// a relationship to another AdObject whos "PrimaryEmail" matches
// the "ForwardedTo" column of this AdObject. There will not always
// be a match though, so not too important just wondering if its possible.
public AdObject ForwardedToObject { get; set; }
// This would be a list of forwards where the "ForwardFrom"
// column matches the "PrimaryEmail" of this AdObject.
public ICollection<Forward> ScheduledForwards { get; set; }
= new List<Forward>();
// FYI... Technically ID,SamAccountName,PrimaryEmail,DistinguishedName,
// and CanonicalName are all unique. They could all be keys.
}
public class Forward
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string ForwardFrom { get; set; }
public string ForwardTo { get; set; }
public bool? DeliverAndRedirect { get; set; }
public DateTime? StartTime { get; set; }
public DateTime? StopTime { get; set; }
public string Recurrence { get; set; }
public bool? DisableForwardAtLogon { get; set; }
public DateTime? DisableAtLogonAfter { get; set; }
public string Notify { get; set; }
public string StartJobId { get; set; }
public string StopJobId { get; set; }
public string StartJobStatus { get; set; }
public string StopJobStatus { get; set; }
public DateTime? StartJobCompleted { get; set; }
public DateTime? StopJobCompleted { get; set; }
public DateTime? StartJobCreated { get; set; }
public DateTime? StopJobCreated { get; set; }
public string StartReason { get; set; }
public string StopReason { get; set; }
// This would be the AdObject whos "PrimaryEmail" matches the
// "ForwardTo" column.
public AdObject ForwardToObject { get; set; }
// This would be the AdObject whos "PrimaryEmail" matches the
// "ForwardFrom" column.
public AdObject ForwardFromObject { get; set; }
}
I think I got it figured out. I was having a hell of a time understanding the logic behind relationships. I had a few misconceptions that I ironed out and after going through every YouTube video, PluralSight Course and Udemy course I could find it finally started to click. I usually don't have this much trouble teaching myself these things, but the misconceptions I had were pointing me in the wrong direction. In the end I only had to specify the keys and two relationships (conventions did the rest).
public class AdObject
{
[Key, Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string ObjectType { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string DisplayName { get; set; }
public string DistinguishedName { get; set; }
[Key, Column(Order = 1)]
public string PrimaryEmail { get; set; }
public string Alias { get; set; }
public string SamAccountName { get; set; }
public string PrimaryDisplay { get; set; }
public string CanonicalName { get; set; }
public string OU { get; set; }
public string CoreGroup { get; set; }
public bool? IsDisabled { get; set; }
public bool? IsForwarded { get; set; }
public bool? DeliverAndRedirect { get; set; }
public bool? DisableForwardAtLogon { get; set; }
public DateTime? DisableAtLogonAfter { get; set; }
public string Notify { get; set; }
public DateTime? LastLogon { get; set; }
public DateTime? LastApiLogon { get; set; }
public DateTime? LastCheck { get; set; }
public AdObject ForwardedToObject { get; set; }
public ICollection<Forward> ForwardRecipientSchedule { get; set; }
= new List<Forward>();
public ICollection<Forward> ForwardSchedule { get; set; }
= new List<Forward>();
}
public class Forward
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public AdObject ForwardFromObject { get; set; }
public AdObject ForwardToObject { get; set; }
public bool? DeliverAndRedirect { get; set; }
public DateTime? StartTime { get; set; }
public DateTime? StopTime { get; set; }
public string Recurrence { get; set; }
public bool? DisableForwardAtLogon { get; set; }
public DateTime? DisableAtLogonAfter { get; set; }
public string Notify { get; set; }
public string StartJobId { get; set; }
public string StopJobId { get; set; }
public string StartJobStatus { get; set; }
public string StopJobStatus { get; set; }
public DateTime? StartJobCompleted { get; set; }
public DateTime? StopJobCompleted { get; set; }
public DateTime? StartJobCreated { get; set; }
public DateTime? StopJobCreated { get; set; }
public string StartReason { get; set; }
public string StopReason { get; set; }
}
public class EntityContext : DbContext
{
public EntityContext() : base("name=EnityContext"){
}
public DbSet<AdObject> AdObjects { get; set; }
public DbSet<Forward> Forwards { get; set; }
//protected override void OnConfiguring(DbContext)
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<AdObject>()
.HasMany(f => f.ForwardSchedule)
.WithRequired(f => f.ForwardFromObject)
.WillCascadeOnDelete(false);
modelBuilder.Entity<AdObject>()
.HasMany(f => f.ForwardRecipientSchedule)
.WithRequired(f => f.ForwardToObject)
.WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
}

Categories