I have a list of information that I keep in the session. Want a LINQ to join this this list and a table of the database.
The result is coming reset, nothing. What am I doing wrong?
Class of List:
public class ASOProcedimentoTemp
{
public int FuncionarioID { get; set; }
public int ProcedimentoID { get; set; }
}
Class of table database:
public class ASOProcedimento : IEntidadeBase
{
[Key]
public int ASOProcedimentoID { get; set; }
public int ASOID { get; set; }
[ForeignKey("ASOID")]
public virtual ASO ASO { get; set; }
public int ProcedimentoID { get; set; }
[ForeignKey("ProcedimentoID")]
public virtual Procedimento Procedimento { get; set; }
public DateTime DtProcedimento { get; set; }
}
My LINQ:
var dadosTemp = HttpContext.Current.Session["ASOProcedimentoTemp"] as List<ASOProcedimentoTemp>;
if (dadosTemp == null)
dadosTemp = new List<ASOProcedimentoTemp>();
result =
(from a in dados.AsQueryable()
join b in dadosTemp on a.ProcedimentoID equals b.ProcedimentoID
select new
{
a.ProcedimentoID,
a.Procedimento.Descricao
})
.Where(where, filtro)
.OrderBy(orderna + " " + ordenaTipo);
The Contains will cause a SQL Where In clause with your IDs in your sql call.
var dadosTemp = HttpContext.Current.Session["ASOProcedimentoTemp"] as List<ASOProcedimentoTemp>;
if (dadosTemp == null)
dadosTemp = new List<ASOProcedimentoTemp>();
var procedimentoIDs = dadosTemp.Select(a => a.ProcedimentoID).ToList();
result =
(from a in dados
where procedimentoIDs.Contains(a.ProcedimentoID)
select new
{
a.ProcedimentoID,
a.Procedimento.Descricao
});
Related
I am creating a dashboard in ASP.NET MVC using C# and Entity Framework.
I have two tables
Tbl_Channel (Id, Channel_Name)
Tbl_News (Id, Channel_Id, News_Title, News_Description)
When I tried this query:
public ActionResult Dashboard()
{
ShowData model = new ShowData();
var rs1 = (from c in db.Tbl_Channel select c).ToList();
var rs2 = (from c in db.Tbl_News
join d in db.Tbl_Channel on c.Channel_Id equals d.Id
select new
{
c.Id,
c.News_Title,
c.News_Description,
d.Channel_Name
})
.OrderByDescending(x => x.Id)
.ToList();
model.tbl_ChannelData = rs1;
model.tbl_NewsData = rs2;
return View(model);
}
I get the following error in line model.tbl_NewsData = rs2:
Model class :
public class ShowData
{
public List<Tbl_Channel> tbl_ChannelData { get; set; }
public List<Tbl_News> tbl_NewsData { get; set; }
}
Error:
Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'System.Collections.Generic.List
The output I want to display be like:
(Id, Channel_Name, News_Title, News_Description)
The root cause of the problem is this: you have defined your properties in the model class like this:
public class ShowData
{
public List<Tbl_Channel> tbl_ChannelData { get; set; }
public List<Tbl_News> tbl_NewsData { get; set; }
}
Yet, your query selects an anonymous type:
select new
{
c.Id,
c.News_Title,
c.News_Description,
d.Channel_Name
}
This causes the error. What you need to do is instantiate objects of the type defined on your model class, e.g.
select new Tbl_News
{
c.Id,
c.News_Title,
c.News_Description,
d.Channel_Name
}
or if this anonymous type doesn't match any existing type yet, you need to define a suitable type
public class ChannelAndNews
{
public int ChannelId { get; set; }
public string NewsTitle { get; set; }
public string NewsDescription { get; set; }
public string ChannelName { get; set; }
}
and create instances of that type, which you can then assign to the model class properties:
select new ChannelAndNews
{
ChannelId = c.Id,
NewsTitle = c.News_Title,
NewsDescription = c.News_Description,
ChannelName = d.Channel_Name
}
Changing query to this one maybe it work:
var query = (from c in db.tblnews
join d in db.tblchannel on c.Channel_Id equals d.Id
Select new Data()
{
Id = c.Id,
News_Title= c.News_Title,
News_Description= c.News_Description,
Channel_Name= d.Channel_Name
})
.OrderByDescending(x => x.Id)
.ToList();
return View(query)
create this class:
public class Data
{
public int Id{ get; set; }
public string News_Title{ get; set; }
public string News_Description{ get; set; }
public string Channel_Name{ get; set; }
}
Your Expected Result:[Just Assumption]
[]1
The Classes Needed:[In Your Case]
public class Tbl_Channel
{
public int Id { get; set; }
public string Channel_Name { get; set; }
}
public class Tbl_News
{
public int Id { get; set; }
public int Channel_Id { get; set; }
public string News_Title { get; set; }
public string News_Description { get; set; }
}
public class ChannelsAndNews
{
public int ChannelId { get; set; }
public string Channel_Name { get; set; }
public string News_Title { get; set; }
public string News_Description { get; set; }
}
public class ShowData
{
public List<Tbl_Channel> Channels { get; set; }
public List<Tbl_News> News { get; set; }
public List<ChannelsAndNews> ChannelsAndNews { get; set; }
}
The Controller Method: [Changes]
public ActionResult ShowData()
{
// GetChannels() & GetNews() -- Seeded Locally in your case from DB.
var showDataModel = new ShowData();
showDataModel.Channels = (from channel in GetChannels() select channel).ToList();
showDataModel.News = (from news in GetNews() select news).ToList();
showDataModel.ChannelsAndNews = (from channel in GetChannels()
join news in GetNews() on channel.Id equals news.Channel_Id
select new ChannelsAndNews
{
ChannelId = channel.Id,
Channel_Name = channel.Channel_Name,
News_Title = news.News_Title,
News_Description = news.News_Description
})
.OrderByDescending(channelnews => channelnews.ChannelId)
.ToList();
return View(showDataModel);
}
This just seems to be working fine.
I write a MySql join code, and want to retrive same value from the Dotnetcore linq methods.
My Join code is below:
SELECT GL.Id AS GradeLevels,
CRS.Name AS CourseName,
GL.Title AS GradlevelName,
AVG (ASTSTU.ObtainedMarks)
FROM GradeLevels GL
INNER JOIN Courses AS CRS ON CRS.GradeLevelsID = GL.Id
INNER JOIN Units AS UNT ON UNT.CourseID = CRS.ID
INNER JOIN Lessons AS LSN ON LSN.UnitsId = UNT.Id
INNER JOIN Assignments AS AST ON AST.LessonId = LSN.id
INNER JOIN AssignmentStudents AS ASTSTU ON ASTSTU.AssignmentId = AST.id
WHERE CRS.SchoolSystemsID = "08d6a1f2-26df-4ad5-25d3-2a26960aa3fd" -- School System id.
GROUP BY GL.Id;
Now I want to change above MySQL Join into Dotnet core linq method to create an API that will be Showing, I try to write code for this
public async Task<ICollection<GradeLevels>> GetSchoolSystemGradLevelsAverage(Guid schoolSystemId)
{
List<GradeLevels> dashboadOverAllAverage = new List<GradeLevels>();
var dashboadOverAllAverage1 = await _GpsContext.GradeLevels
.Include(d=>d.Departments)
.ThenInclude(c=>c.Courses.Where(s=>s.SchoolSystemsID ==schoolSystemId))
.ThenInclude(u=>u.Units)
.ThenInclude(l=>l.Lessons)
.ThenInclude(a=>a.Assignment)
.ThenInclude(a=>a.assignmentStudents)
.GroupBy(g=>g.ID)
.ToListAsync();
return dashboadOverAllAverage;
}
Now I want to show the data though API and want to call to fields GradeLvels name and Average Marks.
[HttpGet()]
public async Task<IActionResult> GetCEOGradeLevelAverage(string schoolSystemId)
{
var overallgradeAverages = await _ceoDashboadRepository.GetSchoolSystemGradLevelsAverage(Guid.Parse(schoolSystemId));
List<GetGradeLevelAverageVm> getOverallAverageVms = new List<GetGradeLevelAverageVm>();
foreach (GradeLevels overallgradeAverage in overallgradeAverages)
{
getOverallAverageVms.Add(new GetGradeLevelAverageVm
{
Marks = overallgradeAverage.Id.ToString(), //Want to show lable of AvrageMark
Name = overallgradeAverage.Name //Want to show Gradelevel name
});
}
return Ok(getOverallAverageVms);
}
You do select too much from your DB. Here an example, how to select the nessecary values:
using (TestDbContext ctx = new TestDbContext())
{
var tmp = ctx.AssignmentStudents
.Include(s => s.Assignment) // Include all Childs..
.ThenInclude(a => a.Lesson)
.ThenInclude(l => l.Unit)
.ThenInclude(u => u.Course)
.ThenInclude(c => c.GradeLevel)
.Where(a => a.LessonId == 123)
.GroupBy(g => // Group by your Key-Values Grade and Course (You could take names instead of ids. Just for simplification)
new
{
GradeLevel = g.Assignment.Lesson.Unit.Course.GradeLevel.Id,
Course = g.Assignment.Lesson.Unit.Course.Id
})
.Select(s => // Select the result into an anonymous type
new
{
GradeLevels = s.Key.GradeLevel, // with same keys like grouping
Course = s.Key.Course,
AverageObtainedMarks = s.Average(a => a.ObtainedMarks) // and an average ObtainedMarks from objects matching the key
})
.Where(s => s.GradeLevel == 1);
foreach (var t in tmp)
{
Console.WriteLine(t.GradeLevels + " " + t.Course + ": " + t.AverageObtainedMarks);
}
}
Here a the classes and dbcontext I used:
public class GradeLevel
{
public int Id { get; set; }
public List<Course> Courses { get; set; }
}
public class Course
{
public int Id { get; set; }
public int GradeLevelId { get; set; }
public GradeLevel GradeLevel { get; set; }
public List<Unit> Units { get; set; }
}
public class Unit
{
public int Id { get; set; }
public int CourseId { get; set; }
public Course Course { get; set; }
public List<Lesson> Lessons { get; set; }
}
public class Lesson
{
public int Id { get; set; }
public int UnitId { get; set; }
public Unit Unit { get; set; }
public List<Assignment> Assignments { get; set; }
}
public class Assignment
{
public int Id { get; set; }
public int LessonId { get; set; }
public Lesson Lesson { get; set; }
public List<AssignmentStudent> AssignmentStudents { get; set; }
}
public class AssignmentStudent
{
public int Id { get; set; }
public int AssignmentId { get; set; }
public Assignment Assignment { get; set; }
public decimal ObtainedMarks { get; set; }
}
public class TestDbContext : DbContext
{
public DbSet<AssignmentStudent> AssignmentStudents { get; set; }
public DbSet<Assignment> Assignments { get; set; }
public DbSet<Lesson> Lessons { get; set; }
public DbSet<Unit> Units { get; set; }
public DbSet<Course> Courses { get; set; }
public DbSet<GradeLevel> GradeLevels { get; set; }
}
I am trying to join two of my tables with linq based on an id, so far unseccesfully.
Here is how my models look :
public class WorkRole
{
public int WorkRoleId { get; set; }
public string RoleName { get; set; }
public string RoleDescription { get; set; }
public int CompanyId { get; set; }
public virtual Company Company { get; set; }
public virtual ICollection<WorkRolesUsersDetails> WorkRolesUsersDetails { get; set; }
}
public class WorkRolesUsersDetails
{
public int WRUDId { get; set; }
public int? WorkRoleId { get; set; }
public string UserDetailsId { get; set; }
public virtual WorkRole WorkRole { get; set; }
public virtual UserDetails UserDetails { get; set; }
public DateTime FocusStart { get; set; }
public DateTime FocusEnd { get; set; }
public bool isActive { get; set; }
}
I am trying to get in one view WorkRoleId, RoleName, RoleDescription and CompanyId from the first table and UserDetailsId, FocusStart, FocusEnd and isActive from the second table.
The farthest i got with my ideas was :
var query = db.WorkRoles.Join(db.WorkRolesUsersDetails,x => x.WorkRoleId,y => y.WorkRoleId,(x, y) => new { wr = x, wrud = y });
But sadly, it didn't work. I just don't know enough linq and couldn't get much out of other questions/answers here. Please, help.
Code for joining 2 tables is:
var list = db.WorkRoles.
Join(db.WorkRolesUsersDetails,
o => o.WorkRoleId, od => od.WorkRoleId,
(o, od) => new
{
WorkRoleId= o.WorkRoleId
RoleName= o.RoleName,
RoleDescription= o.RoleDescription,
CompanyId= o.CompanyId,
WRUDId= od.WRUDId,
UserDetailsId= od.UserDetailsId,
FocusStart=od.FocusStart,
FocusEnd=od.FocusEnd
})
If you are using EF may I suggest the Includes statement it works wonders. IF you have a foreign key assigned. It basically gets the other data with it.
static void Main(string[] args)
{
using (var context = new TesterEntities())
{
var peopleOrders = context.tePerson.Include("teOrder").First(p => p.PersonId == 1).teOrder.ToList();
peopleOrders.ForEach(x => Console.WriteLine($"{x.OrderId} {x.Description}"));
}
}
Combining manually without navigation context option.
public class Student
{
public int StudentID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public List<StudentTestScore> Scores { get; set; }
}
public class StudentTestScore
{
public int StudentID { get; set; }
public int Score { get; set; }
}
class Program
{
static void Main(string[] args)
{
var students = new List<Student>
{
new Student { StudentID = 1, FirstName = "Brett", LastName = "X" },
new Student { StudentID = 2, FirstName = "John", LastName = "X" }
};
var grades = new List<StudentTestScore> { new StudentTestScore { StudentID = 1, Score = 98 } };
var combined = students.Join(grades, x => x.StudentID, y => y.StudentID,
(x, y) => new
{
Student = $"{x.FirstName} {x.LastName}",
Grade = y.Score
}).ToList();
combined.ForEach(x => Console.WriteLine($"{x.Student} {x.Grade}"));
Console.ReadLine();
}
Here i Have two tables with some columns.Here my aim is i want to do GroupBy operatio using ChilsMaster
public partial class Master
{
public int MasterId { get; set; }
public string Prod_Name { get; set; }
public string Produ_Adress { get; set; }
public Nullable<decimal> Price { get; set; }
}
public partial class ChildMasterMaster
{
public int ChildId { get; set; }
public Nullable<int> MasterId { get; set; }
public string SalesRec { get; set; }
public Nullable<bool> Prod_Deliver { get; set; }
}
public class Market_Masters
{
public int MasterId { get; set; }
public string Prod_Name { get; set; }
public string Produ_Adress { get; set; }
public Nullable<decimal> Price { get; set; }
public int ChildId { get; set; }
public string SalesRec { get; set; }
public Nullable<bool> Prod_Deliver { get; set; }
}
Here I write one private file which contains both columns of the table by using this join:
public IEnumerable<Market_Masters> GetMaster()
{
var x = from n in db.Masters
join chil in db.ChildMasterMasters on n.MasterId equals chil.MasterId into t
select new
{
n.MasterId,
n.Prod_Name,
n.Produ_Adress,
n.Price,
Hello = t
};
return ???;
}
If I write .ToList() it throws an Exception
You are currently returning an anonymous type defined by:
select new
{
n.MasterId,
n.Prod_Name,
n.Produ_Adress,
n.Price,
Hello = t
};
You cannot expose that as a strongly typed return type, precisely because it is anonymous. There is no Foo for which you can say "this is IEnumerable<Foo>".
You should probably create a named class that matches what you want, and return new YourNewType {...} (and return IEnumerable<YourNewType>)
You can't return anonymous types from a method (i.e. select new { ... }). You need to create a class for that or use Market_Masters if it is of that type, e.g.:
public IEnumerable<Market_Masters> GetMaster()
{
var x = from n in db.Masters
join chil in db.ChildMasterMasters on n.MasterId equals chil.MasterId into t
select new Market_Masters()
{
MasterId = n.MasterId,
Prod_Name = n.Prod_Name,
Produ_Adress = n.Produ_Adress,
Price = n.Price,
Hello = t
};
return x.ToList();
}
If the type returned is not Market_Masters you could do something like (replace YourChildType with your actual type):
public class MarketMastersWithHello : Market_Masters
{
public IEnumerable<YourChildType> Hello { get; set; }
}
and then:
public IEnumerable<MarketMastersWithHello> GetMaster()
{
var x = from n in db.Masters
join chil in db.ChildMasterMasters on n.MasterId equals chil.MasterId into t
select new MarketMastersWithHello()
{
MasterId = n.MasterId,
Prod_Name = n.Prod_Name,
Produ_Adress = n.Produ_Adress,
Price = n.Price,
Hello = t
};
return x.ToList();
}
Hi i have a collection In mongoDB that i want to get only part of the fields from it, i created a class that i'm inserting data with to Mongo
ClassCode:
public class FrameDocument
{
public ObjectId _id { get; set; }
public Nullable<System.DateTime> FrameTimeStamp { get; set; }
public Nullable<int> ActivePick { get; set; }
public Nullable<int> TraderId { get; set; }
public Nullable<int> EventCodeId { get; set; }
public byte[] Frame { get; set; }
public int ServerUserId { get; set; }
public int SesionId { get; set; }
public string TraderName { get; set; }
public string ServerUserName { get; set; }
}
This is the insert code:
FrameDocument frameDoc = new FrameDocument();
frameDoc.Frame = imageBA;
frameDoc.EventCodeId = 1;
frameDoc.SesionId = 1;
frameDoc.FrameTimeStamp = DateTime.Now;
frameDoc.ServerUserId = (int)toMongoDt.Rows[0]["ServerUserId"];
frameDoc.TraderId = (int)toMongoDt.Rows[0]["TraderId"];
frameDoc.ActivePick = (int)toMongoDt.Rows[0]["ActivePick"];
frameDoc.TraderName = (string)toMongoDt.Rows[0]["TraderName"];
frameDoc.ServerUserName = (string)toMongoDt.Rows[0] ["ServerUserName"];
var mongoCon = "mongodb://127.0.0.1";
MongoClient client = new MongoClient(mongoCon);
var db = client.GetDatabase("Video");
var frameCollection = db.GetCollection<FrameDocument>("Frame");
frameCollection.InsertOne(frameDoc);
**For now i get all The fields from the collection with this code, But i want to leave the Frame field out of the class, i tried to build different class without this field but i don't know how to not receive the Frame field **
var collection = db.GetCollection<BsonDocument>("Frame");
var builder = Builders<BsonDocument>.Filter;
var filter = builder.Eq("SesionId", 1)
& builder.Eq("TraderId", 125)
& builder.Eq("ServerUserId", 1)
& builder.Lt("FrameTimeStamp", sing.eDate)
& builder.Gt("FrameTimeStamp", sing.sDate);
var result = collection.Find(filter).ToList();
Can anyone help?
please see this:
_result = _collection.Find(o => o._id == _id)
.Project<FrameDocumentNoFrameField>
(Builders<FrameDocument>.Projection.Exclude(f => f.Frame)).ToList();
where FrameDocumentNoFrameField is a class without Frame field
source here
#Example: Model class
public class Company
{
public string CompanyId { get; set; }
public string CompanyName { get; set; }
public List<CompanySettings>{ get; set; }
}
[BsonIgnoreExtraElements]
public class CompanySettings
{
public CompanySetupType CompanySetupTypeId { get; set; }
public List<string> CompanyEmployee{ get; set; }
}
#Now create a Projection class for which you want to read values
[BsonIgnoreExtraElements]
public class CompanySettingsProjectionModel
{
public List<CompanySettings> CompanySettings { get; set; }
}
#After Creating projection,fetch data from mongo using Builders
public async Task<CompanySettings> GetCompanySettings(string companyId, short CompanySetupTypeId)
{
var filter = BaseFilter(accountId);
var projection = Builders<Company>.Projection
.Include(x => x.Id)
.Include(x => x.CompanySettings);
FindOptions<Company, CompanySettingsProjectionModel> findOptions = new FindOptions<Company, CompanySettingsProjectionModel>()
{
Projection = projection
};
var companySettings = await (await Collection.FindAsync(filter, findOptions)).FirstOrDefaultAsync();
if (companySettings != null && companySettings.CompanySettings != null && companySettings.CompanySettings.Any())
{
return companySettings.CompanySettings .FirstOrDefault(x => (int)x.CompanySetupTypeId == CompanySetupTypeId);
}
return default;
}