我正在尝试在LINQ中实现SQL查询,但我找不到出错的地方。
原始SQL命令:
SELECT DISTINCT a.art_id, a.art_title,a.art_permalink, MAX(sp.sp_code), MAX(p.pr_cat_name), MAX(p.pr_value), MAX(p.pr_cat_id), MAX(p.pr_cat_id)
FROM vArtPart sp
JOIN vArticle a ON (sp.art_id = a.art_id)
JOIN vPrice p ON (a.art_id = p.art_id)
WHERE
sp.sp_id = 31 AND
a.art_visible = 1 AND
a.lng_id = 1
GROUP BY a.art_id, a.art_title, a.art_permalink
Linq查询尝试(不工作)
var q = (from sp in db.vArtParts
where sp.sp_id == dd_type.SelectedValue.ToInt()
join a in db.vArticles on sp.art_id equals a.art_id into aa
from a in aa.DefaultIfEmpty()
join p in db.vPrices on a.art_id equals p.art_id into pp
from p in pp.DefaultIfEmpty()
where a.art_visible == true && a.lng_id == 1
group sp by new {a.art_id, a.art_title, a.art_permalink} into g
select new
{
art_id = (int?)g.art_id,
g.art_title,
g.art_permalink,
sp_code = g.Max(gg=>gg.sp_code),
pr_cat_name = g.Max(gg=>gg.pr_cat_name),
pr_value = g.Max(gg=>gg.pr_value),
pr_cat_id = (int?)g.Max(gg=>gg.pr_cat_id)
}).ToList();
* upd:相同的LINQ查询在没有分组的情况下工作(但我需要这个):
var q = (from sp in db.vArtParts
where sp.sp_id == dd_type.SelectedValue.ToInt()
join a in db.vArticles on sp.art_id equals a.art_id into aa
from a in aa.DefaultIfEmpty()
join p in db.vPrices on a.art_id equals p.art_id into pp
from p in pp.DefaultIfEmpty()
where a.art_visible == true && a.lng_id == 1
select new
{
art_id = (int?)a.art_id,
a.art_title,
a.art_permalink,
sp.sp_code,
p.pr_cat_name,
p.pr_value,
pr_cat_id = (int?)p.pr_cat_id
}).ToList();
* upd:错误讯息:
错误CS1061:'System.Linq.IGrouping'确实如此 不包含'art_id'的定义,也没有扩展方法'art_id' 接受第一个类型的参数 可以找到'System.Linq.IGrouping'(是 你错过了使用指令或程序集引用?)
ASP.global_asax.Application_Error Error System.Web.HttpParseException (0x80004005): ***\ctrl_search_product.ascx.cs(70): error CS1061: 'System.Linq.IGrouping<AnonymousType#1,vArtPart>' does not contain a definition for 'art_id' and no extension method 'art_id' accepting a first argument of type 'System.Linq.IGrouping<AnonymousType#1,vArtPart>' could be found (are you missing a using directive or an assembly reference?) ---> System.Web.HttpCompileException (0x80004005): c:\inetpub\vhosts\domostroy-msk.ru\httpdocs\inc\ctrl_search_product.ascx.cs(70): error CS1061: 'System.Linq.IGrouping<AnonymousType#1,vArtPart>' does not contain a definition for 'art_id' and no extension method 'art_id' accepting a first argument of type 'System.Linq.IGrouping<AnonymousType#1,vArtPart>' could be found (are you missing a using directive or an assembly reference?)
at System.Web.Compilation.BuildManager.PostProcessFoundBuildResult(BuildResult result, Boolean keyFromVPP, VirtualPath virtualPath)
at System.Web.Compilation.BuildManager.GetBuildResultFromCacheInternal(String cacheKey, Boolean keyFromVPP, VirtualPath virtualPath, Int64 hashCode, Boolean ensureIsUpToDate)
at System.Web.Compilation.BuildManager.GetVPathBuildResultFromCacheInternal(VirtualPath virtualPath, Boolean ensureIsUpToDate)
at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
at System.Web.UI.BaseTemplateParser.GetReferencedType(VirtualPath virtualPath, Boolean allowNoCompile)
at System.Web.UI.BaseTemplateParser.GetUserControlType(VirtualPath virtualPath)
at System.Web.UI.MainTagNameToTypeMapper.ProcessUserControlRegistration(UserControlRegisterEntry ucRegisterEntry)
at System.Web.UI.BaseTemplateParser.ProcessDirective(String directiveName, IDictionary directive)
at System.Web.UI.TemplateControlParser.ProcessDirective(String directiveName, IDictionary directive)
at System.Web.UI.PageParser.ProcessDirective(String directiveName, IDictionary directive)
at System.Web.UI.TemplateParser.ParseStringInternal(String text, Encoding fileEncoding)
at System.Web.UI.TemplateParser.ProcessException(Exception ex)
at System.Web.UI.TemplateParser.ParseStringInternal(String text, Encoding fileEncoding)
at System.Web.UI.TemplateParser.ParseString(String text, VirtualPath virtualPath, Encoding fileEncoding)
at System.Web.UI.TemplateParser.ParseFile(String physicalPath, VirtualPath virtualPath)
at System.Web.UI.TemplateParser.ParseInternal()
at System.Web.UI.TemplateParser.Parse()
at System.Web.Compilation.BaseTemplateBuildProvider.get_CodeCompilerType()
at System.Web.Compilation.BuildProvider.GetCompilerTypeFromBuildProvider(BuildProvider buildProvider)
at System.Web.Compilation.BuildProvidersCompiler.ProcessBuildProviders()
at System.Web.Compilation.BuildProvidersCompiler.PerformBuild()
at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath)
at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
at System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean throwIfNotFound)
at System.Web.Compilation.BuildManager.CreateInstanceFromVirtualPath(VirtualPath virtualPath, Type requiredBaseType, HttpContext context, Boolean allowCrossApp)
at System.Web.UI.PageHandlerFactory.GetHandlerHelper(HttpContext context, String requestType, VirtualPath virtualPath, String physicalPath)
at System.Web.UI.PageHandlerFactory.GetHandler(HttpContext context, String requestType, String virtualPath, String path)
at System.Web.HttpApplication.MaterializeHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
答案 0 :(得分:1)
由于您正在进行分组,因此在最终选择中需要
select new
{
art_id = (int?)g.key.art_id,
g.key.art_title,
g.key.art_permalink,
...
}
此外,但与您看到的错误无关,在您发布的SQL版本中,您正在进行内部联接,但在LINQ版本中,您正在执行左外部联接;你应该删除DefaultIfEmpty行。
编辑:由于你现在遇到最后的选择部分有问题,这里是后一个错误的答案(请注意'group sp by ...'成为新组{sp,p} by ...' -
var q = (from sp in db.vArtParts
where sp.sp_id == dd_type.SelectedValue.ToInt()
join a in db.vArticles on sp.art_id equals a.art_id
join p in db.vPrices on a.art_id equals p.art_id
where a.art_visible == true && a.lng_id == 1
group new {sp, p} by new {a.art_id, a.art_title, a.art_permalink} into g
select new
{
art_id = (int?)g.Key.art_id,
g.Key.art_title,
g.Key.art_permalink,
sp_code = g.Max(gg=>gg.sp.sp_code),
pr_cat_name = g.Max(gg=>gg.p.pr_cat_name),
pr_value = g.Max(gg=>gg.p.pr_value),
pr_cat_id = (int?)g.Max(gg=>gg.p.pr_cat_id)
}).ToList();