我正在努力让LINQ语句正常工作。
我在这篇文章后尝试过使用SQL语法和lambda:
C# Joins/Where with Linq and Lambda
这就是我工作的SQL的样子:
SELECT ws_lookup_OccupationGroup.Code
FROM ws_lookup_OccupationGroup
INNER JOIN ws_lookup_Occupation ON
ws_lookup_OccupationGroup.Code = ws_lookup_Occupation.ws_lookup_OccupationGroup_Code
WHERE (ws_lookup_Occupation.Code = N'413')
这是我的第一次尝试,但没有结果:
var query = from occupationGroup in db.ws_lookup_OccupationGroups
join occupations in db.ws_lookup_Occupations on occupationGroup.Code equals occupations.Code
where occupations.Code == model.Client.Client_Details_Enhanced.Occupation.Code
select new
{
OccupationGroup = occupationGroup,
Occupations = occupations
};
这是我使用Lamdba的第二次尝试,但也没有结果:
var queryLambda = db.ws_lookup_OccupationGroups
.Join(db.ws_lookup_Occupations,
occupation => occupation.Code,
occupationGroup => occupationGroup.Code,
(occupation, occupationGroup) => new
{
OCCUPATION = occupation,
OCCUPATIONGROUP = occupationGroup
})
.Where(all => all.OCCUPATION.Code == model.Client.Client_Details_Enhanced.Occupation.Code);
我只是看不出有什么问题......
我不知道这是否有任何相关性,但我使用的是Code First Entity Framework - 他是我职业组的模型&职业:
public class ws_lookup_OccupationGroup {
[Key]
[MaxLength(250)]
public string Code { get; set; }
[MaxLength(250)]
public string Name { get; set; }
public int SortOrder { get; set; }
public List<ws_lookup_Occupation> Occupations { get; set; }
}
public class ws_lookup_Occupation {
[Key]
[MaxLength(10)]
public string Code { get; set; }
[MaxLength(250)]
public string Name { get; set; }
[MaxLength(250)]
public string BarbadosMotorFactor { get; set; }
[MaxLength(250)]
public string TrinidadMotorFactor { get; set; }
[MaxLength(250)]
public string OtherRegionsMotorFactor { get; set; }
}
答案 0 :(得分:3)
我宁愿提出策略建议,而不是直接回答你的问题。然后,一种策略是添加一个扩展方法,该方法将显示您的实体框架查询或IQueryable将运行的SQL。这可以通过创建单元测试并执行测试驱动开发方法或TDD的方式完成。
您知道要获得预期结果的SQL。最好使用EF查询,直到获得一个能够提供您所获得结果的SQL。您可以调试集成测试,然后按照最终结果 - 您正在使用的SQL - 在Entity Framework Linq to Entities代码中编写。
首先,我们可以创建以下扩展方法:
public static class IQueryableExtensions
{
/// <summary>
/// Shows the sql the IQueryable query will be generated into and executed on the DbServer
/// </summary>
/// <param name="query">The IQueryable to analyze</param>
/// <param name="decodeParameters">Set to true if this method should try decoding the parameters</param>
/// <remarks>This is the generated SQL query in use for Entity Framework</remarks>
public static string ShowSql(this IQueryable query, bool decodeParameters = false)
{
var objectQuery = (ObjectQuery)query;
string result = ((ObjectQuery)query).ToTraceString();
if (!decodeParameters)
return result;
foreach (var p in objectQuery.Parameters)
{
string valueString = p.Value != null ? p.Value.ToString() : string.Empty;
if (p.ParameterType == typeof(string) || p.ParameterType == typeof(DateTime))
valueString = "'" + valueString + "'";
result = result.Replace("@" +p.Name, p.Value != null ? valueString : string.Empty);
}
return result;
}
}
然后我们需要一些集成测试,来自我自己的系统的样本:
[TestFixture]
public class IqueryableExtensionsTest
{
[Test]
public void QueryableReturnsSqlAndDoesNotThrow()
{
using (var dbContext = ObjectContextManager.ScopedOpPlanDataContext)
{
var operations = from operation in dbContext.Operations
where operation.Status == (int) OperationStatusDataContract.Postponed
&& operation.OperatingDate >= new DateTime(2015, 2, 12)
select operation;
string sql = operations.ShowSql();
Assert.IsNotNull(sql);
}
}
}
虽然您当然可以使用Linqpad查找您所追求的EF查询和SQL,但此策略的好处是您可以在Visual Studio中使用它来处理更复杂的现实场景,您还可以获得更好的调试经验比在VS和Linqpad之间切换。
如果您调试此类集成测试,则可以观察正在生成的SQL。请注意,如果要运行Integration Test而不进行调试,也可以执行 Console.WriteLine 或 Debug.WriteLine 来观察输出。
答案 1 :(得分:2)
在您的SQL中,您将加入以下
ws_lookup_OccupationGroup.Code = ws_lookup_Occupation.ws_lookup_OccupationGroup_Code
但是你在Linq加入
occupationGroup.Code equals occupations.Code
根据您实体的具体情况,我认为您确实需要这个
occupationGroup.Code = occupations.ws_lookup_OccupationGroup_Code
根据您的实体,您可以使用导航属性而不是加入
来执行以下操作var query = from occupationGroup in db.ws_lookup_OccupationGroups
where occupationGroup.Occupations.Any(
o => o.Code == model.Client.Client_Details_Enhanced.Occupation.Code)
select occupationGroup;
获取至少一个拥有所需代码的职业的所有职业组。或者,如果你只想要小组和职业的组合,那么你可以做到
var query = from occupationGroup in db.ws_lookup_OccupationGroups
from occupation in occupationGroup.Occupations
where occupation.Code == model.Client.Client_Details_Enhanced.Occupation.Code
select new
{
occupationGroup,
occupation
};