EF Core Linq Query Syntax - linq

I'm trying to replicate a view inside EF. The original view used a UNION operator so have split my initial query here in tow to better match. Having some issues working out my syntax. I am trying to query the groups, get their primary contact details. Also get all vehicles and their linked groups. I believe I have specified the ContactLink requirement correctly in the first query.
[BindProperty]
public IList<OrgChartNode> OrgChartNodes { get; set; }
public JsonResult OnGet(string OrgCode)
{
IList<OrgChartNode> OrgChartGroups = _db.Groups
.Include(g => g.ContactLinks)
.ThenInclude(gtc => gtc.Contact)
.Include(g => g.Organisation)
.Where(g => g.OrgCode.Equals(OrgCode))
.Where(g => g.ContactLinks.Any(cl => cl.LinkTypeId == 1))
.Select(g => new OrgChartNode
{
Id = g.Id,
Name = g.Name,
TierId = g.TierId,
ParentGroupId = g.ParentGroupId,
OrgName = g.Organisation.Name,
OrgCode = g.OrgCode,
ContactName = g.ContactLinks.**Contact**.Name,
ContactEmail = g.ContactLinks.**Contact**.Phone,
ContactPhone = g.ContactLinks.**Contact**.Email,
ContactId = g.ContactLinks.**Contact**.ContactId,
})
.OrderByDescending(g => g.TierId)
.ThenBy(g => g.Name)
.AsNoTracking()
.ToList();
IList<OrgChartNode> OrgChartUnits = _db.Units
.Include(u => u.GroupLinks)
.Include(u => u.Organisation)
.Where(u => u.OrgCode.Equals(OrgCode))
.Select(u => new OrgChartNode
{
Id = u.NodeId,
Name = u.Name,
TierId = 0,
ParentGroupId = u.GroupLinks.**GroupId**,
OrgName = u.Organisation.Name,
OrgCode = u.OrgCode,
ContactName = "",
ContactEmail = "",
ContactPhone = "",
ContactId = 0,
})
.OrderBy(u => u.Name)
.AsNoTracking()
.ToList();
OrgChartNodes = OrgChartGroups.Concat(OrgChartUnits)
.ToList();
return new JsonResult(OrgChartNodes);
}
The four Contact fields have been marked wih **. They have red intellisense lines in Visual Studio. Looks like it cat follow to Contact, despite it being ThenInclude() above. So does the GroupId in the second query. Hovering over the acronym/aliases tells me they appear to be the correct classes.
Listed below are the three data classes. You can see the Navigation properties. Are they configured correctly?
How can I include the contact details in my .Select() call?
Group.cs
[Table("Report_Group")]
public class Group
{
[Key, Required, Column("GroupId")]
public int Id { get; set; }
[Required, MaxLength(5)]
public string OrgCode { get; set; }
[Required, MaxLength(100)]
public string Name { get; set; }
public int TierId { get; set; }
public int? ParentGroupId { get; set; }
public int? CostCenter { get; set; }
[Required]
public int ExcludeFromAlertStats { get; set; }
[Required]
public int GroupTypeId { get; set; }
[ForeignKey("ParentGroupId")]
public virtual Group Parent { get; set; }
[ForeignKey("OrgCode")]
public virtual Organisation Organisation { get; set; }
[ForeignKey("TierId")]
public virtual Tier Tier { get; set; }
[ForeignKey("GroupTypeId")]
public virtual GroupType GroupType { get; set; }
[InverseProperty("GroupId")]
public virtual IList<GroupToUnitLink> UnitLinks { get; set; }
[InverseProperty("GroupId")]
public virtual IList<GroupToContactLink> ContactLinks { get; set; }
}
GroupToContactLink.cs
This classes key is set using fluent in OnModelCreating() as it is a composite key.
[Table("Report_Link_Group_to_Contact")]
public class GroupToContactLink
{
public GroupToContactLink()
{
}
public GroupToContactLink(int contactId, int groupId, int linkTypeId)
{
this.ContactId = contactId;
this.GroupId = groupId;
this.LinkTypeId = linkTypeId;
}
[Required]
public int ContactId { get; set; }
[Required]
public int GroupId { get; set; }
[Required]
public int LinkTypeId { get; set; }
[ForeignKey("ContactId")]
public virtual Contact Contact { get; set; }
[ForeignKey("GroupId")]
public virtual Group Group { get; set; }
[ForeignKey("LinkTypeId")]
public virtual ContactLinkType LinkType { get; set; }
}
Contact.cs
[Table("Report_Contact")]
public class Contact
{
/// <summary>
/// Primary Key for Contact in the database
/// </summary>
[Key, Column("ContactId")]
public int Id { get; set; }
/// <summary>
/// Foreign Key indicating <see cref="Data.Organisation"/>
/// </summary>
[Required, StringLength(5)]
public string OrgCode { get; set; }
/// <summary>
/// Name of Contact
/// </summary>
[Required, StringLength(100)]
public string Name { get; set; }
/// <summary>
/// Phone number of contact. Needs to be in +614 format for SMS to work
/// </summary>
[StringLength(12)]
public string Phone { get; set; }
/// <summary>
/// Email Address for Contact
/// </summary>
[StringLength(255), EmailAddress]
public string Email { get; set; }
/// <summary>
/// Navigation property to <see cref="Data.Organisation"/>
/// </summary>
[ForeignKey("OrgCode")]
public virtual Organisation Organisation { get; set; }
[InverseProperty("ContactId")]
public virtual IList<GroupToContactLink> GroupLinks { get; set; }
}

Related

InvalidCastException: Unable to cast object of type 'System.Collections.Generic.List to System.Collections.Generic.IEnumerable

I am trying to implementation clean architecture in netcore and I have Runtime Error
InvalidCastException: Unable to cast object of type 'System.Collections.Generic.List to System.Collections.Generic.IEnumerable
In the WebUI I have Match controller and ViewAllMatch Action like this
public async Task<IActionResult> ViewAllMatch()
{
var matches = await _mediator.Send(new GetMatchesDetail());
return View(matches);
}
In the application Layer I have A queries like this:
public class GetMatchesDetail : IRequest<IEnumerable<MatchesDetail>>
{
}
public class MatchesDetail
{
public string MatchId { get; set; }
public int MatchNumer { get; set; }
public DateTime DateMatch { get; set; }
public TimeSpan TimeMatch { get; set; }
public int MatchYear { get; set; }
public string SeasonId { get; set; }
public string Round { get; set; }
/// <summary>
/// Set value to Qualified for Qualified and Final for Final Round
/// </summary>
public string Stage { get; set; }
public string SubStage { get; set; }
public string HTeam { get; set; }
public string HTeamCode { get; set; } //For Flag get from Table Team from Foreign Key TeamName
public int HGoal { get; set; }
public int GGoal { get; set; }
public string GTeam { get; set; }
public string GTeamCode { get; set; }
public string WinNote { get; set; }
public string Stadium { get; set; }
public string Referee { get; set; }
public long Visistors { get; set; }
public string Status { get; set; }
}
public class GetMatchesHandler : IRequestHandler<GetMatchesDetail, IEnumerable<MatchesDetail>>
{
private readonly IMatchRepository _matchRepository;
public GetMatchesHandler(IMatchRepository matchRepository)
{
_matchRepository = matchRepository;
}
public async Task<IEnumerable<MatchesDetail>> Handle(GetMatchesDetail request, CancellationToken cancellationToken)
{
var matchlistview = await _matchRepository.GetMatchDetailAsync();
return matchlistview;
}
}
And the code for matchRepository to get all the match in Infastructure like this.
public async Task<IEnumerable<MatchesDetail>> GetMatchDetailAsync()
{
var matchDetailList = (from match in _context.Matches
join team1 in _context.Teams on match.HTeam equals team1.TeamName
join team2 in _context.Teams on match.GTeam equals team2.TeamName
join season in _context.Seasons on match.SeasonId equals season.SeasonId
select new
{
match.MatchId,
match.MatchNumber,
match.DateMatch,
match.TimeMatch,
match.MatchYear,
match.SeasonId,
season.SeasonName,
match.Round,
match.Stage,
match.SubStage,
match.HTeam,
HTeamCode = team1.TeamCode,
match.HGoal,
match.GGoal,
match.GTeam,
GTeamCode = team2.TeamCode,
match.WinNote,
match.Stadium,
match.Referee,
match.Visistors
});
return (IEnumerable<MatchesDetail>)await matchDetailList.ToListAsync();
}
Full code have been upload to Github at https://github.com/nguyentuananh921/Betting.git.
for more detail.
Thanks for your help.
I am so confuse about model in clean architech when i have more entities and the model I want to view in the WebUI contain many entities in domain.
Thanks for your help.
I have Modify public IEnumerable GetMatchDetailAsync() like that.
public IEnumerable<MatchesDetail> GetMatchDetailAsync()
{
#region TryOther way
var matchQuery = (from match in _context.Matches
join team1 in _context.Teams on match.HTeam equals team1.TeamName
join team2 in _context.Teams on match.GTeam equals team2.TeamName
join season in _context.Seasons on match.SeasonId equals season.SeasonId
select new
{
#region selectResult
//Remove to clear Select what I want to get.
#endregion
});
MatchesDetail matchesDetail = new MatchesDetail();
List<MatchesDetail> retList = new List<MatchesDetail>();
//IEnumerable<MatchesDetail> retList;
foreach (var item in matchQuery)
{
#region ManualMapping
matchesDetail.MatchId = item.MatchId;
//other field mapping
#endregion
retList.Add(matchesDetail);
}
#endregion
return retList;
}
And it work

How to debug AutoMapper "Missing type map configuration or unsupported mapping" error

I have seen plenty of examples of this error occuring, for a wide variety of causes and I have gone through all the causes I can see, but still i get the error, so I am wondering if some one can give some information about what this error actually means, so i can try finding the cause. Here is some code:
Controller:
[HttpPost]
public ActionResult Edit(ProfileViewModel model)
{
if (ModelState.IsValid)
{
var person = new UserAttribute();
person = Mapper.Map<ProfileViewModel, UserAttribute>(model);
db.UserAttribute.Add(person);
db.SaveChanges();
}
View Model
public class ProfileViewModel
{
[Display(Name = "First Name")]
[StringLength(20)]
[Required]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
[StringLength(30)]
[Required]
public string LastName { get; set; }
[Display(Name = "Gender")]
[Required]
public string Gender { get; set; }
[Display(Name = "Date of Birth")]
[DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}", ApplyFormatInEditMode = true)]
public DateTime DOB { get; set; }
[Display(Name = "Hair Color")]
public string HairColor { get; set; }
[Display(Name = "Eye Color")]
public string EyeColor { get; set; }
[Display(Name = "Body Type")]
public string Weight { get; set; }
[Display(Name = "Height")]
public string HeightFeet { get; set; }
public string HeightInches { get; set; }
public int UserId { get; set; }
public IEnumerable<SelectListItem> WeightList { get; set; }
public IEnumerable<SelectListItem> EyeColorList { get; set; }
public IEnumerable<SelectListItem> HairColorList { get; set; }
public IEnumerable<SelectListItem> HeightFeetList { get; set; }
public IEnumerable<SelectListItem> HeightInchesList { get; set; }
public IEnumerable<SelectListItem> GenderList { get; set; }
}
UserAttribute model:
public int ProfileId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public System.DateTime DOB { get; set; }
public string HairColor { get; set; }
public string EyeColor { get; set; }
public string HeightFeet { get; set; }
public string Weight { get; set; }
public int UserId { get; set; }
public string HeightInches { get; set; }
Mapping config:
public class AutoMapperConfiguration
{
public static void Configure()
{
Mapper.Initialize(x => x.AddProfile<ViewToDomainMapProfile>());
Mapper.Initialize(x => x.AddProfile<DomainToViewMapProfile>());
}
}
public class ViewToDomainMapProfile : Profile
{
public override string ProfileName
{
get { return "ViewToDomainMapProfile"; }
}
protected override void Configure()
{
Mapper.CreateMap<ProfileViewModel, UserAttribute>()
.ForSourceMember(x => x.GenderList, y => y.Ignore())
.ForSourceMember(x => x.HairColorList, y => y.Ignore())
.ForSourceMember(x => x.EyeColorList, y => y.Ignore())
.ForSourceMember(x => x.WeightList, y => y.Ignore())
.ForSourceMember(x => x.HeightFeetList, y => y.Ignore())
.ForSourceMember(x => x.HeightInchesList, y => y.Ignore());
}
}
and the config is called in the global asax:
AutoMapperConfiguration.Configure();
Using Mapper.AssertConfigurationIsValid(); produces the following exception:
AutoMapper.AutoMapperConfigurationException :
Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
==============================================================================================
ProfileViewModel -> UserAttribute (Destination member list)
----------------------------------------------------------------------------------------------
ProfileId
So, you need to add mapping for ProfileId.
Overall, it's a good practice to use Mapper.AssertConfigurationIsValid(); either in your unit tests (you have them, right?), or after your mapper configuration. It'll display detailed information for such a misconfigurations.
For the viewmodel => userattribute
I noticed that ProfileId is a destination property, but not a source property.
public int ProfileId { get; set; }
Do you need to add code to ingore this destination member?
Other:
I might also suggest using or customizing the automapper to map properties that present that match by name exclusively.
Also, when possible, please avoid model names ending in the word Attritribute as by convention this is used almost exclusively for actual attributes. (my apologies for nitpicking)

TryUpdateModel Error

First time I can add Allergies into my DB without a problem is As below screen.
But when I try to add 2nd record (after save the first record) then it gives below mentioned run time exception (is as below screen).
Run time Exception
An error occurred while saving entities that do not expose foreign key
properties for their relationships. The EntityEntries property will
return null because a single entity cannot be identified as the source
of the exception. Handling of exceptions while saving can be made
easier by exposing foreign key properties in your entity types. See
the InnerException for details.
Stack Trace (this is for when I try to add 2nd record for medical table.But it is same for Allergies Table also)
Violation of PRIMARY KEY constraint 'PK__Medicati__3214EC0768A0EA12'.
Cannot insert duplicate key in object 'dbo.Medications'. The statement
has been terminated.
Action Method
[HttpPost]
public ActionResult EditMedicalInfo(string providerKey, string ownerKey, string petKey)
{
var pet = Repository.GetPet(ownerKey, petKey);
if (TryUpdateModel(pet))
{
Repository.Save();
}
var url = Url.AbsoluteRouteUrl("PetDetail", new { controller = "customers", action = "detail", providerKey = providerKey, ownerKey = ownerKey, petKey = petKey }) + "#medical";
return Redirect(url);
}
Pet Model
public class Pet {
public Pet() { Id = Guid.NewGuid(); Created = DateTime.Now; }
public Guid Id { get; set; }
public virtual Owner Owner { get; set; }
[StringLength(50), Required]
public string Name { get; set; }
public string Key { get; set; }
public DateTime Created { get; set; }
[Display(Name = "Birth Date"), DataType(DataType.Date)]
public DateTime? BirthDate { get; set; }
[EnumDataType(typeof(PetType)), UIHint("EnumerationList")]
[Required]
public int Type { get; set; }
[Required]
public Guid BreedId { get; set; }
[Display(Name = "Breed"), ForeignKey("BreedId")]
public virtual Breed Breed { get; set; }
[EnumDataType(typeof(Gender)), UIHint("EnumerationList")]
[Required]
public int? Gender { get; set; }
public double Weight { get; set; }
[Display(Name = "License #")]
public string LicenseNumber { get; set; }
[Display(Name = "Microchip #")]
public string MicrochipNumber { get; set; }
public int? AgeValue { get { return (BirthDate.HasValue) ? (int)(DateTime.Today - BirthDate.Value).TotalDays : default(int?); } }
public string Age { get { return (BirthDate.HasValue) ? BirthDate.Value.ToAge() : "Unknown"; } }
public virtual ICollection<PetPhoto> Photos { get; set; }
public virtual ICollection<Appointment> Appointments { get; set; }
public virtual ICollection<MedicalRecordOrder> Orders { get; set; }
public virtual ICollection<PetDocument> Documents { get; set; }
public virtual ICollection<PetNote> Notes { get; set; }
public virtual ICollection<PetProvider> Providers { get; set; }
public virtual ICollection<PetService> PetServices { get; set; }
public Guid? Avatar { get; set; }
public virtual MedicalRecord Medical { get; set; }
public virtual BehavioralRecord Behavioral { get; set; }
public virtual DietRecord Diet { get; set; }
public Guid? EmergencyVeterinarianId { get; set; }
[ForeignKey("EmergencyVeterinarianId")]
public virtual Provider EmergencyVeterinarian { get; set; }
public virtual ICollection<PetContact> Contacts { get; set; }
[EnumDataType(typeof(ProfileCreatorType))]
public int ProfileCreator { get; set; }
[EnumDataType(typeof(PetClassification)), UIHint("EnumerationList")]
public int Classification { get; set; }
[UIHint("InsuranceCarrier")]
public virtual string InsuranceCarrier { get; set; }
// Non persisted extensions
/// <summary>
/// Non Persisted
/// </summary>
[NotMapped]
public List<AppointmentInfo> AppointmentInfos { get; set; }
/// <summary>
/// Non Persisted
/// </summary>
[NotMapped]
public List<AppointmentInfo> SiblingAppointmentInfos { get; set; }
public IList<ReservationRequest> ReservationRequests { get; set; }
[UIHint("QuickList")]
public virtual ICollection<SpecialInstruction> SpecialInstructions { get; set; }
public virtual PetSitterRestrictionPermission PetSitterRestrictionPermission { get; set; }
public virtual PetSitterBehavior PetSitterBehavior { get; set; }
public virtual PetSitterCleaningRecord PetSitterCleaningRecord { get; set; }
public virtual PetSitterNote PetSitterNote { get; set; }
}
Allergy Model
public class Allergy {
public Allergy() { Id = Guid.NewGuid(); }
[ScaffoldColumn(false)]
public Guid Id { get; set; }
public string Name { get; set; }
public string Treatment { get; set; }
}
How could I avoid above error when I try to add 2nd record ?

nop commerce automapper exception, missing type map configuration or unsupported mapping

I have tried to debug and find where the mismatch is coming from but I can not. Any ideas about where to look?
here is the model
public class PatientModel : BaseNopEntityModel
{
public PatientModel()
{
AvailableStates = new List<SelectListItem>();
}
[NopResourceDisplayName("Patient.Fields.FirstName")]
[AllowHtml]
public string FirstName { get; set; }
[NopResourceDisplayName("Patient.Fields.LastName")]
[AllowHtml]
public string LastName { get; set; }
[NopResourceDisplayName("Patient.Fields.MiddleName")]
[AllowHtml]
public string MiddleName { get; set; }
[NopResourceDisplayName("Patient.Fields.RoomNumber")]
[AllowHtml]
public string RoomNumber { get; set; }
[NopResourceDisplayName("Patient.Fields.HospitalName")]
[AllowHtml]
public string HospitalName { get; set; }
[NopResourceDisplayName("Patient.Fields.StateProvince")]
public int? StateProvinceId { get; set; }
[NopResourceDisplayName("Patient.Fields.StateProvince")]
[AllowHtml]
public string StateProvince { get; set; }
[NopResourceDisplayName("Patient.Fields.City")]
[AllowHtml]
public string City { get; set; }
[NopResourceDisplayName("Patient.Fields.ZipPostalCode")]
[AllowHtml]
public string ZipPostalCode { get; set; }
public IList<SelectListItem> AvailableStates { get; set; }
public bool FirstNameDisabled { get; set; }
public bool LastNameDisabled { get; set; }
public bool MiddleNameDisabled { get; set; }
public bool RoomNumberDisabled { get; set; }
public bool HospitalNameDisabled { get; set; }
public bool StateProvinceDisabled { get; set; }
public bool CityDisabled { get; set; }
public bool ZipPostalCodeDisabled { get; set; }
}
and here is the entity that it is trying to map to
public class Patient : BaseEntity, ICloneable
{
/// <summary>
/// Gets or sets the first name
/// </summary>
public virtual string FirstName { get; set; }
/// <summary>
/// Gets or sets the last name
/// </summary>
public virtual string LastName { get; set; }
/// <summary>
/// Gets or sets the middle name
/// </summary>
public virtual string MiddleName { get; set; }
/// <summary>
/// Gets or sets the patient room number
/// </summary>
public virtual string RoomNumber { get; set; }
public virtual string HospitalName { get; set; }
/// <summary>
/// Gets or sets the state/province identifier
/// </summary>
public virtual int? StateProvinceId { get; set; }
/// <summary>
/// Gets or sets the state/province
/// </summary>
public virtual StateProvince StateProvince { get; set; }
/// <summary>
/// Gets or sets the city
/// </summary>
public virtual string City { get; set; }
/// <summary>
/// Gets or sets the zip/postal code
/// </summary>
public virtual string ZipPostalCode { get; set; }
public virtual DateTime CreatedOnUtc { get; set; }
public object Clone()
{
var pat = new Patient()
{
FirstName = this.FirstName,
LastName = this.LastName,
MiddleName = this.MiddleName,
RoomNumber = this.RoomNumber,
HospitalName = this.HospitalName,
StateProvince = this.StateProvince,
StateProvinceId = this.StateProvinceId,
City = this.City,
ZipPostalCode = this.ZipPostalCode,
CreatedOnUtc = DateTime.UtcNow
};
return pat;
}
}
and mapper where the issue occurs
public static PatientModel ToModel(this Patient entity)
{
return Mapper.Map<Patient, PatientModel>(entity);
}
That means you never called Mapper.CreateMap<>() for those two types.
I found a way of getting it to work correctly the only problem was I had to change
public static PatientModel ToModel(this Patient entity)
{
return Mapper.Map<Patient, PatientModel>(entity);
}
and remove the mapper and do it manually to map the patient entitiy to the model.

LINQ query not returning all results due to null value on Entity Framework Core only

I have two rows of test data and am able to pull back the first row with no problems but can't get the second row to return. Digging around and testing shows that this is probably due to the AppovedByID column being null in the row that is not being returned. I have looked but can't figure out how to modify my LINQ query so it will return all rows even if the child table can't be linked in due to a null value.
The Query:
public JsonResult ChangeOrders()
{
var ChangeOrdersList = _DbContext.ChangeOrders
.Include(co => co.ApprovalStatus)
.Include(co => co.ApprovedBy)
.Include(co => co.AssignedTo)
.Include(co => co.CreatedBy)
.Include(co => co.CurrentStatus)
.Include(co => co.Impact)
.Include(co => co.Priority)
.Include(co => co.ChangeType)
.Select(co => new ChangeOrderListVM()
{
ApprovalStatus = co.ApprovalStatus.Name,
ApprovedBy = string.Concat(co.ApprovedBy.FirstName, ' ', co.ApprovedBy.LastName),
AssignedTo = string.Concat(co.AssignedTo.FirstName, ' ', co.AssignedTo.LastName),
CreatedBy = string.Concat(co.CreatedBy.FirstName, ' ', co.CreatedBy.LastName),
CurrentStatus = co.CurrentStatus.Name,
DateApproved = co.DateApproved,
DateCompleated = co.DateCompleated,
DateCreated = co.DateCreated,
DateStarted = co.DateStarted,
EstimatedEndDate = co.EstimatedEndDate,
EstimatedStartDate = co.EstimatedStartDate,
ID = co.ID,
Impact = co.Impact.Name,
Name = co.Name,
Priority = co.Priority.Name,
Reason = co.ReasonForChange,
Type = co.ChangeType.Name
}).ToList();
return Json(ChangeOrdersList);
}
ChangeOrders:
public class ChangeOrder
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public short? ApprovedByUserID { get; set; }
public byte ApprovalStatusID { get; set; }
public short AssignedToUserID { get; set; }
public short CreatedByUserID { get; set; }
public byte CurrentStatusID { get; set; }
public DateTime? DateApproved { get; set; }
public DateTime? DateCompleated { get; set; }
public DateTime DateCreated { get; set; }
public DateTime? DateStarted { get; set; }
public DateTime EstimatedStartDate { get; set; }
public DateTime EstimatedEndDate { get; set; }
public byte ImpactID { get; set; }
public byte PriorityID { get; set; }
public byte TypeID { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string ReasonForChange { get; set; }
[ForeignKey("ApprovalStatusID")]
public ChangeApprovalStatus ApprovalStatus { get; set; }
[ForeignKey("ApprovedByUserID")]
public User ApprovedBy { get; set; }
[ForeignKey("AssignedToUserID")]
public User AssignedTo { get; set; }
[ForeignKey("CreatedByUserID")]
public User CreatedBy { get; set; }
[ForeignKey("CurrentStatusID")]
public ChangeStatus CurrentStatus { get; set; }
[ForeignKey("ImpactID")]
public ChangeImpact Impact { get; set; }
[ForeignKey("PriorityID")]
public ChangePriority Priority { get; set; }
[ForeignKey("TypeID")]
public ChangeType ChangeType { get; set; }
}
Users:
public class User
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public short ID { get; set; }
[Required]
public string ADUserName { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
public string Email { get; set; }
[Required]
public string Phone { get; set; }
[Required]
public DateTime LastUpdated { get; set; }
}
EDIT:
This is apparently unique to Entity Framework 7 (AKA Core) as it works fine in EF 6. I am in fact using EF7 and as an additional test I updated a single line
ApprovedBy = string.Concat(co.ApprovedBy.FirstName, ' ', co.ApprovedBy.LastName),
and changed it to this
ApprovedBy = "",
and all the rows are returning so I then tried to do
ApprovedBy = (co.ApprovedByUserID.HasValue) ? string.Concat(co.ApprovedBy.FirstName, ' ', co.ApprovedBy.LastName) : "",
but that give a very odd error:
incorrect syntax near the keyword 'is'
This is a bug in the library. I have reported the bug for fixing in the next version on github

Resources