[英]Is there any way to retrieve data based on multple where from multiple table
I have been trying for a while to do this in every possible way.我一直在尝试以各种可能的方式做到这一点。 I have a table name employees and other table name qualifications我有表名employees等表名资格
Every employee has qualifications, but on initial basis qualification of every employee has not been filled into database.每个员工都有资格,但在最初的基础上,每个员工的资格并没有被填入数据库。
I have tried VIA EF and LINQ and raw SqlConnection
and SqlCommand
as well but still not getting good results.我也尝试过 VIA EF 和 LINQ 以及原始的SqlConnection
和SqlCommand
,但仍然没有得到好的结果。
Employees WITH PHD is retrieved by拥有 PHD 的员工检索方式为
ViewData["lecturer_phd"] = _context.TblQualification
.Count(q => q.QualificationType == 4 &&
q.Employee.DesignationCode == 3);
and NON PHD should get back with和非博士应该回来
ViewData["lecturer_nphd"] = _context.TblEmployees
.Count(e => e.DesignationCode == 3 &&
e.EmployeeQualifications.Any(q => q.QualificationType != 4));
But this is not working and I am not familiar with LINQ as well but I tried that as well not any result.但这不起作用,我也不熟悉 LINQ 但我也试过了,没有任何结果。
The raw SQL query is using this code:原始 SQL 查询使用以下代码:
SqlConnection con = new SqlConnection(_context.Database.GetConnectionString());
DbCommand cmd = new SqlCommand("SELECT Count(*) FROM [DbBzuCC].[dbo].[tblEmployees] LEFT JOIN tblQualifications ON tblEmployees.Employee_Code = tblQualifications.Employee_Code AND tblQualifications.qualification_type != 4 WHERE tblEmployees.Designation_Code = 3",
con);
con.Open();
ViewData["lecturer_nphd"] = (int) cmd.ExecuteScalar();
con.Close();
But all in vain.但一切都是徒劳的。 Any help will be appreciated.任何帮助将不胜感激。 I will be thankful for any help from community.我将感谢社区的任何帮助。 Thanks in advance提前致谢
Actually qualification_type was null where it was not entered for any employee so In sql query we need to check实际上,qualification_type 是 null 没有为任何员工输入,所以在 sql 查询中我们需要检查
ISNULL like this ISNULL 像这样
SELECT COUNT(*)
FROM [DbBzuCC].[dbo].[tblEmployees]
Left join tblQualifications ON tblEmployees.Employee_Code = tblQualifications.Employee_Code
WHERE tblEmployees.Designation_Code = 3 AND ISNULL(tblQualifications.qualification_type,1) != 4
And in entity framework you can do it like this在实体框架中你可以这样做
_context.TblEmployees
.Count(e => e.DesignationCode == 3 && e.EmployeeQualifications.All(q => q.QualificationType != 4));
Thanks everyone for your precious time.感谢大家宝贵的时间。
Regards,问候,
So you have Employees
and Qualifications
, and a one-to-many relation: every Employee
has zero or more Qualifications
, every Qualification
is the Qualification
of exactly one Employee
, namely the Employee that the foreign key EmployeeCode refers to.所以你有Employees
和Qualifications
,并且是一对多的关系:每个Employee
有零个或多个Qualifications
,每个Qualification
都是恰好一个Employee
的Qualification
,即外键 EmployeeCode 所指的 Employee 。
If you have followed the entity framework conventions , you will have classes similar to:如果您遵循实体框架约定,您将拥有类似于以下内容的类:
class Employee
{
public int Id {get; set;}
public string Name {get; set;}
...
// Every Employee has zero or more Qualifications (one-to-many)
public virtual ICollection<Qualification> {get; set;}
}
class Qualification
{
public int Id {get; set;}
public string Description {get; set;}
...
// Every qualification is the qualification of exactly one Employee using foreign key
public int EmployeeId {get; set;}
public virtual Employee Employee {get; set;}
}
This would be enough for entity framework to detect the tables, the columns in the tables, and the relations between the tables using the primary keys and foreign keys.这足以让实体框架使用主键和外键检测表、表中的列以及表之间的关系。
In entity framework the columns of the tables are represented by the non-virtual properties.在实体框架中,表的列由非虚拟属性表示。 The virtual properties represent the relations between the tables (one-to-many, many-to-many)虚拟属性表示表之间的关系(一对多、多对多)
The foreign key Qualification.EmployeeId
is a real column, hence it it non-virtual.外键Qualification.EmployeeId
是一个真实的列,因此它是非虚拟的。 Property Qualfication.Employee
represents the relation, hence it is virtual.属性Qualfication.Employee
表示关系,因此它是虚拟的。
There is only need for attributes nor fluent API if you deviate from the conventions, like you did in your foreign key.如果您偏离约定,就像您在外键中所做的那样,只需要属性也不需要流利的 API。 In DbContext.OnModelCreating:在 DbContext.OnModelCreating 中:
modelBuilder.Entity<Employee>().HasKey(employee => employee.EmployeeCode);
modelBuilder.Entity<Employee>().HasMany(employee => employee.Qualifications)
.WithRequired(qualification => qualification.Employee)
.HasForeignKey(qualification => qualification.EmployeeCode);
In words: every Employee has a primary key in property EmployeeCode.换句话说:每个 Employee 在 EmployeeCode 属性中都有一个主键。 Every Employee has zero or more Qualifications in property Employee.Qualifications.每个 Employee 在 Employee.Qualifications 属性中都有零个或多个 Qualifications。 Every Qualification has exactly one Employee in property Qualification.Employee, using foreign key Qualificatioin.EmployeeCode.每个 Qualification 在属性 Qualification.Employee 中只有一个 Employee,使用外键 Qualificatioin.EmployeeCode。
Requirement: count the number of qualifications with qualification_type != 4 for Employees that have Designation_Code == 3要求:为具有 Designation_Code == 3 的员工计算具有qualification_type != 4 的资格数量
Usig the virtual ICollection this is straightforward:使用虚拟 ICollection 这很简单:
int qualificationTypeToIgnore == 4;
int employeeDesignationCode == 3;
var result = dbContext.Qualifications.Where(qualification =>
qualification.QualificationType != qualificationTypeToIgnore &&
qualification.Employee.DesignationCode == employeeDesignationCode)
.Count();
In words: from all Qualifications, keep only those Qualifications that have a QualificationType unequal to qualificationTypeToIgnore that also belongs to an Employee that has a DesingationCode equal to employeeDesignationCode.换句话说:从所有 Qualifications 中,只保留那些 QualificationType 不等于qualificationTypeToIgnore 的 Qualifications,它也属于 DesingationCode 等于 employeeDesignationCode 的 Employee。 Count the number of remaining Qualifications.计算剩余的资格数。
Entity framework knows the one-to-many relation, and will do the property Join for you.实体框架知道一对多关系,并且会为你做属性 Join。
Some people don't like to use the virtual properties, they prefer to do the join themselves.有些人不喜欢使用虚拟属性,他们更喜欢自己进行连接。
var eligibleEmployees = dbContext.Employees
.Where(employee => Employee.DesignationCode == employeeDesignationCode);
var eligibleQualifications = dbContext.Qualifications
.Where(qualification => qualification.QualificationType != qualificationTypeToIgnore);
var result = eligibleQualifications.Join(eligibleEmployees,
qualification => qualification.EmployeeCode, // from every Qualification take the foreign key
employee => employee.EmployeeCode, // from every Employee take the primary key
// parameter resultSelector: from every (qualification, employee) combination make one new
(qualification, employee) => new {qualification, employee})
.Count();
Since you will not be using the join result, you could simplify parameter resultSelector:由于您不会使用连接结果,您可以简化参数 resultSelector:
(qualification, employee) => 1
Or let entity framework do the join:或者让实体框架做连接:
var result = eligibleQualifications.Where(qualification => eligibleEmployees
.Any(employee => employee.EmployeeCode == qualification.EmployeeCode))
.Count();
From all eligible qualifications, count the number of qualifications that have an EmployeeCode that is also an EmployeeCode in the eligible Employees.从所有符合条件的资格中,计算具有 EmployeeCode 的资格的数量,该 EmployeeCode 也是符合条件的员工中的 EmployeeCode。
IMHO the solution using the virtual properties is the most elegant one.恕我直言,使用虚拟属性的解决方案是最优雅的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.