public class JobDescription
{
public int JobDescriptionID { get; set; }
//
public virtual List<Image> Image { get; set; }
}
public class Image
{
public int ImageID { get; set; }
[Required]
public int JobDescriptionID { get; set; }
[ForeignKey("JobDescriptionID")]
public virtual JobDescription JobDescription { get; set; }
public virtual List<ImageSection> ImageSection { get; set; }
}
public class ImageSection
{
public int ImageSectionID { get; set; }
//
public int ImageID { get; set; }
[ForeignKey("ImageID")]
public virtual Image Image { get; set; }
public virtual DigitalSection DigitalSection { get; set; }
}
public class DigitalSection
{
public int DigitalSectionID { get; set; }
public int ImageSectionID { get; set; }
[ForeignKey("ImageSectionID")]
public virtual ImageSection ImageSection { get; set; }
public virtual VerifiedSection VerifiedSection { get; set; }
}
public class VerifiedSection
{
public int VerifiedSectionID { get; set; }
public string DigitizedText { get; set; }
public int DigitalSectionID { get; set; }
[ForeignKey("DigitalSectionID")]
public virtual DigitalSection DigitalSection { get; set; }
}
I am using CodeFirst approach and I have JobDscriptionID. Now i want to retireve all the DigitizedText from VerifiedSection Table. How to do it ?
Try this :
var result = contetx.VerifiedSection
.Where(V => V.DigitalSection.ImageSection.Image.JobDescription.JobDescriptionID == 1)
.Select(V => V.DigitizedText);
Alternately you could also use Join
var result = context.VerifiedSection.Join(context.DigitalSection.Join(
(context.ImageSection.Join
(context.Image.Join
(context.JobDescription.Where(J=> .JobDescriptionID == 1)), I=> I.JobDescriptionID, J => J.JobDescriptionID , (I,J) => I)
IS => IS.ImageID, I=> I.ImageID, (IS,I) => IS)
D => D.ImageSectionID, IS => IS.ImageSectionID , (D,IS) => D)
V => V.DigitalSectionID, D => D.DigitalSectionID, (V,D) => V.DigitizedText);
Good Luck !!
var query = (from image in Context.Image
Where image.JobDescriptionID == id
select image.ImageID).SingleOrDefault();
var query2 = (from select in Context.ImageSection
Where select.ImageID == query
select select.ImageSectionID).SingleOrDefault();
var query3 = (from digital in Context.DigitalSection
Where digital.ImageSectionID == query2
select digital.DigitalSectionID).SingleOrDefault();
var query4 = from text in Context.VerifiedSection
Where text.VerifiedSection == query3
select select.DigitizedText;
Kundan Singh Chouhan gave you a better answer, but perhaps you'd like to do it the "Queries" way.
Related
Class Brands, Models, Generations, Modification
How to get all Brands for ModificationName == "ACK"
public class Brand
{
public Brand()
{
this.Models = new HashSet<Model>();
}
public int BrandId { get; set; }
public virtual ICollection<Model> Models { get; set; }
}
public class Model
{
public Model()
{
this.Generations = new HashSet<Generation>();
}
public virtual ICollection<Generation> Generations { get; set; }
public int? BrandId { get; set; }
public virtual Brand Brand { get; set; }
}
public class Generation
{
public Generation()
{
this.Modifications = new HashSet<Modification>();
}
public int GenerationId { get; set; }
public virtual ICollection<Modification> Modifications { get; set; }
public int? ModelId { get; set; }
public virtual Model Model { get; set; }
}
public class Modification
{
public int ModificationId { get; set; }
public string ModificationName { get; set; }
public int? GenerationId { get; set; }
public virtual Generation Generation { get; set; }
}
Another approach could be to use the Join operator. For example>
from currentBrand in Context.Brand
join currentModel in context.Model on currentBrand.Id equals currentModel.BrandId
join currentGeneration in context.Generations on currentGeneration.ModelId equals currentModel.id
join currentModeification in context.Modification on currentModeification.GenerationId equals currentGeneration .Id
Where currentModeification.ModificationName == "ACK"
Trick here is to use SelectMany method.
var query =
from b in ctx.Brands
where b.Models
.SelectMany(m => m.Generations.SelectMany(g => g.Modifications))
.Where(m => m.ModificationName == "ACK").Any()
select b;
UPDATE with includes
It will work only with EF Core 5
var query =
from b in ctx.Brands
.Include(b => b.Models)
.ThenInclude(g => g.Generations)
.ThenInclude(m => m.Modifications.Where(x => x.ModificationName == "ACK"))
where b.Models
.SelectMany(m => m.Generations.SelectMany(g => g.Modifications))
.Where(m => m.ModificationName == "ACK").Any()
select b;
I have entity
public class ImageTeam
{
public int Id { get; set; }
public int TeamID { get; set; }
public Team Team { get; set; }
public int PostTeamID { get; set; }
public string Image { get; set; }
public int ImageType { get; set; }
public int StatusPublic { get; set; }
public int StatusActive { get; set; }
public DateTime CreatedAt { get; set; }
}
public class Team
{
public int Id { get; set; }
public string Name { get; set; }
public int NoMember { get; set; }
public float Score { get; set; }
public int StatusActive { get; set; }
public int TeamType { get; set; }
public virtual List<TeamGroup> ListMember { get; set; }
public virtual List<ImageTeam> ListAvatar { get; set; }
public virtual List<ImageTeam> ListBanner { get; set; }
public DateTime CreatedAt { get; set; }
}
config data context
modelBuilder.Entity<Team>(entity =>
{
entity.HasMany(x => x.ListAvatar)
.WithOne(t => t.Team)
.HasForeignKey(pv => pv.TeamID);
});
when I post the data insert a new record entity ImageTeam then it show exception
I need to do...Help me
In the Team class you add another relation ListBanner to ImageTeam class ,you have not set an foreign key for it, so EF automatically creates a TeamID and because TeamId already in the class, it's throw exception . You also need to set an foreign key for second relation.
public class ImageTeam
{
public int Id { get; set; }
public int TeamID { get; set; }
public Team Team { get; set; }
public int BannerTeamId { get; set; }
public Team BannerTeam { get; set; }
public int PostTeamID { get; set; }
public string Image { get; set; }
public int ImageType { get; set; }
public int StatusPublic { get; set; }
public int StatusActive { get; set; }
public DateTime CreatedAt { get; set; }
}
entity.HasMany(x => x.ListAvatar)
.WithOne(t => t.Team)
.HasForeignKey(pv => pv.TeamID).OnDelete(DeleteBehavior.Restrict);
entity.HasMany(x => x.ListBanner)
.WithOne(t => t.BannerTeam)
.HasForeignKey(pv => pv.BannerTeamId).OnDelete(DeleteBehavior.Restrict);
I have found a solution:
edit Team entity:
public class Team
{
public int Id { get; set; }
public string Name { get; set; }
public int NoMember { get; set; }
public float Score { get; set; }
public int StatusActive { get; set; }
public int TeamType { get; set; }
public virtual List<TeamGroup> ListMember { get; set; }
public virtual List<ImageTeam> ListImage { get; set; }
public DateTime CreatedAt { get; set; }
}
*no config data context
create new model: TeamViewModel
public class TeamViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public int NoMember { get; set; }
public float Score { get; set; }
public int StatusActive { get; set; }
public int TeamType { get; set; }
public virtual List<TeamGroupViewModel> ListMember { get; set; }
public virtual List<ImageTeam> ListImage { get; set; }
public string AvatarUrl { get; set; }
public virtual List<ImageTeam> ListAvatar { get; set; }
public string BannerUrl { get; set; }
public virtual List<ImageTeam> ListBanner { get; set; }
public virtual List<ImageTeam> ListPost { get; set; }
}
in controller :
[Route("api/[controller]/{id}/view")]
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
var team = _teamService.GetById(id);
var model = _mapper.Map<TeamViewModel>(team);
model = parserImageTeam(model);
return Ok(model);
}
[Route("api/[controller]/{UserId}/view-teams")]
[HttpGet("{UserId}")]
public IActionResult GetAllTeamOfUser(int UserId)
{
// list teams
var teams = _teamService.GetTeamOfUser(UserId);
var _teams = _mapper.Map<IList<TeamViewModel>>(teams);
var newTeams = new List<TeamViewModel>();
foreach (TeamViewModel team in _teams)
{
newTeams.Add(parserImageTeam(team));
}
return Ok(newTeams);
}
private TeamViewModel parserImageTeam(TeamViewModel teamModel)
{
var imageAvatars = new List<ImageTeam>();
var imageBanners = new List<ImageTeam>();
var imagePosts = new List<ImageTeam>();
bool avt = false, banner = false;
foreach (ImageTeam image in teamModel.ListImage)
{
if (image.ImageType == Constants.ImageType.IMAGE_AVATAR_TEAM)
{
image.Image = parserUrlImage(image);
imageAvatars.Add(image);
if (!avt)
{
teamModel.AvatarUrl = image.Image;
avt = true;
}
}
if (image.ImageType == Constants.ImageType.IMAGE_BANNER_TEAM)
{
image.Image = parserUrlImage(image);
imageBanners.Add(image);
if (!banner)
{
teamModel.BannerUrl = image.Image;
banner = true;
}
}
if (image.ImageType == Constants.ImageType.IMAGE_POST_TEAM)
{
image.Image = parserUrlImage(image);
imagePosts.Add(image);
banner = true;
}
}
teamModel.ListAvatar = imageAvatars;
teamModel.ListBanner = imageBanners;
teamModel.ListPost = imagePosts;
return teamModel;
}
private string parserUrlImage(ImageTeam model)
{
string url = Configuration.GetValue<string>("BaseVariables:BaseUrl");
// another controller handle request (ImagesController)
return model.Image = url + "/Images/" + Constants.ImageType.getFolderName(model.ImageType).ToLower() + "/" + model.TeamID + "?ImageType=" + model.ImageType + "&imageName=" + model.Image;
}
I am trying to query EF models. (GameBank and GameCouponBank) How can I make a projection for left outer join (GoupJoin)?
Can I make projection for Coupons?
Here is my query
var gameBankResult = context.GameBanks.GroupJoin(context.GameCouponBanks, g => g.GameBankID, gc => gc.GameBankID,
(g,gc) => new {
g.quantity,
g.currency,
g.initiationResultCode,
g.productCode,
g.productDescription,
g.referenceId,
g.responseDateTime,
g.unitPrice,
g.totalPrice,
Coupons = gc
})
.Where(g => g.productCode == initiate.productCode)
.Select(s => s);
Here is models:
public class GameBank
{
public int GameBankID { get; set; }
public string referenceId { get; set; }
public string productCode { get; set; }
public int quantity { get; set; }
public string version { get; set; }
public DateTime? requestDateTime { get; set; } = DateTime.Now;
public int? customerID { get; set; }
public string password { get; set; }
public DateTime? responseDateTime { get; set; } = DateTime.Now;
public string initiationResultCode { get; set; }
public string companyToken { get; set; }
public int used { get; set; }
public string productDescription { get; set; }
public string currency { get; set; }
public double unitPrice { get; set; }
public double totalPrice { get; set; }
public virtual List<GameCouponBank> coupons { get; set; }
}
public class GameCouponBank
{
public int Id { get; set; }
public int GameBankID { get; set; }
public DateTime? expiryDate { get; set; }
public string Serial { get; set; }
public string Pin { get; set; }
}
You don't need to use GroupJoin explicitly. You can simply project your query as follows:
var gameBankResult = context.GameBanks.Where(g => g.productCode == initiate.productCode)
.Select(g => new {
g.quantity,
g.currency,
g.initiationResultCode,
g.productCode,
g.productDescription,
g.referenceId,
g.responseDateTime,
g.unitPrice,
g.totalPrice,
Coupons = g.coupons.Select(c => new {c.Id, c.GameBankID,...}).ToList() //<-- Here is the projection for coupons
}).FirstOrDefault(); // I assume you are returning single entity, if not then use `.ToList()` instead of `.FirstOrDefault()`
I have an entity called Insurance like this:
public class Insurance : BaseEntity, IExpirationDocument
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public override int Id { get; set; }
[Column(TypeName = "NVARCHAR")]
[StringLength(256)]
public string PathToCertificate { get; set; }
[Column(TypeName = "NVARCHAR")]
[StringLength(50)]
public string Filename { get; set; }
public int Value { get; set; }
public string Name => InsuranceType.Name;
public DateTime ExpiryDate { get; set; }
public DateTime IssueDate { get; set; }
public bool Active { get; set; }
public int InsuranceTypeId { get; set; }
public virtual InsuranceType InsuranceType { get; set; }
public int InsurerId { get; set; }
public virtual Insurer Insurer { get; set; }
public int ApplicantId { get; set; }
public virtual Applicant Applicant { get; set; }
public int? DocumentEmailHistoryId { get; set; }
public virtual DocumentEmailHistory DocumentEmailHistory { get; set; }
public Insurance()
{
Active = true;
}
}
Would it be possible to do this type of query with Entity Framework:
SELECT *
FROM Insurances i1
INNER JOIN
(SELECT
insuranceTypeId, applicantid, MAX(IssueDate) as 'maxissuedate'
FROM
Insurances
GROUP BY
insuranceTypeId, applicantid) AS i2 ON i1.applicantid = i2.applicantid
AND i1.insuranceTypeId = i2.insuranceTypeId
WHERE
i1.issueDate = i2.maxissuedate
If you are trying to get latest issued Insurance according to InsuranceTypeId and ApplicantId you can group data according to needed properties, order by IssueDate descendingly and take only one Insurance info. Of course it will not give you the same query but it will give you the same result:
var result = context.Insurances
.GroupBy(m => new { m.InsuranceTypeId , m.ApplicantId })
.Select( g => new
{
MaxInsurance = g.OrderByDescending(m => m.IssueDate)
.Take(1)
})
.SelectMany(m => m.MaxInsurance);
What is the best solutions to retrieve records from child table in relation?
I cannot include the solution file in this question.
Model
[Table("Tbl_DefaultValue")]
public class DefaultValue
{
[Key]
public int DefaultValue_ID { get; set; }
public string DefaultVal_Name { get; set; }
public virtual ICollection<DefaultValue_Det> DefaultValue_Det { get; set; }
}
[Table("Tbl_DefaultValue_Det")]
public class DefaultValue_Det
{
[Key]
public int DefaultValue_Det_ID { get; set; }
public int DefaultValue_ID { get; set; }
public string DefaultValue_Value { get; set; }
public virtual DefaultValue DefaultValue { get; set; }
public virtual ICollection<Car> Cars { get; set; }
}
Controller
driverdt.TypeList =
new SelectList(db.DefaultValue_Det
.Where(a => a.DefaultValue_ID == db.DefaultValue
.Where(d => d.DefaultVal_Name == "marid")
.Max(b=>b.DefaultValue_ID)), "DefaultValue_Det_ID", "DefaultValue_Value");
return View( driverdt);
You can pre-populate collection DefaultValue_Det using FetchMany:
driverdt.TypeList =
new SelectList(db.DefaultValue_Det
.Where(a => a.DefaultValue_ID == db.DefaultValue
.Where(d => d.DefaultVal_Name == "marid")
.Max(b=>b.DefaultValue_ID))
.FetchMany(x => x.DefaultValue_Det)
, "DefaultValue_Det_ID", "DefaultValue_Value");