Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 关于查找缺少的密钥的查询是否可以改进?(SQL或LINQ)_C#_Sql_Sql Server_Linq - Fatal编程技术网

C# 关于查找缺少的密钥的查询是否可以改进?(SQL或LINQ)

C# 关于查找缺少的密钥的查询是否可以改进?(SQL或LINQ),c#,sql,sql-server,linq,C#,Sql,Sql Server,Linq,我正在开发一个ASP.NETMVC网站,并正在寻找一种改进此例程的方法。它可以在LINQ级别或SQL Server级别进行改进。我希望我们最多能在一次查询电话内完成 以下是相关表格和一些示例数据: 我们不限制每个键都必须有每个LanguageId值,实际上业务逻辑不允许这样的限制。但是,在应用程序级别,我们希望警告管理员某个键缺少某个/某些语言值。所以我有这个类和查询: public class LocalizationKeyWithMissingCodes { public stri

我正在开发一个ASP.NETMVC网站,并正在寻找一种改进此例程的方法。它可以在LINQ级别或SQL Server级别进行改进。我希望我们最多能在一次查询电话内完成

以下是相关表格和一些示例数据:

我们不限制每个
都必须有每个
LanguageId
值,实际上业务逻辑不允许这样的限制。但是,在应用程序级别,我们希望警告管理员某个键缺少某个/某些语言值。所以我有这个类和查询:

public class LocalizationKeyWithMissingCodes
{
    public string Key { get; set; }
    public IEnumerable<string> MissingCodes { get; set; }
}
public class LocalizationKeyWithMissingCodes
{
公共字符串密钥{get;set;}
公共IEnumerable缺失代码{get;set;}
}
此方法获取键列表以及任何缺少的代码(例如,如果我们有en+jp+ch语言代码,并且键只有en+ch的值,则列表将包含jp):

public IEnumerable GetAllKeysWithMissingCodes()
{
var languageList=Utils.ResolveDependency().GetActive();
var languageIdList=languageList.Select(q=>q.Id);
var languageIdDictionary=languageList.ToDictionary(q=>q.Id);
var keyList=this.GetActive()
.选择(q=>q.Key)
.Distinct();
var result=新列表();
foreach(键列表中的var键)
{
//获取丢失的代码
var existingCodes=this.Get(q=>q.Active&&q.Key==Key)
.Select(q=>q.LanguageId);
//ToList,以确保在申请时对其进行处理
var missingLangId=languageList.Where(q=>!existingCodes.Contains(q.Id))
.ToList();
结果.添加(新的LocalizationKeyWithMissingCodes()
{
键=键,
MissingCodes=missingLangId
.Select(q=>languageIdDictionary[q.Id].Code),
});
}
result=result.OrderByDescending(q=>q.MissingCodes.Count()>0)
.ThenBy(q=>q.Key)
.ToList();
返回结果;
}
我认为我当前的解决方案不好,因为它会对每个键进行查询调用。有没有一种方法可以改进它,或者使它更快,或者在一个查询调用中打包

编辑:这是答案的最终查询:

    public IQueryable<LocalizationKeyWithMissingCodes> GetAllKeysWithMissingCodes()
    {
        var languageList = Utils.ResolveDependency<ILanguageRepository>().GetActive();
        var localizationList = this.GetActive();

        return localizationList
            .GroupBy(q => q.Key, (key, items) => new LocalizationKeyWithMissingCodes()
            {
                Key = key,
                MissingCodes = languageList
                    .GroupJoin(
                        items,
                        lang => lang.Id,
                        loc => loc.LanguageId,
                        (lang, loc) => loc.Any() ? null : lang)
                    .Where(q => q != null)
                    .Select(q => q.Code)
            }).OrderByDescending(q => q.MissingCodes.Count() > 0) // Show the missing keys on the top
            .ThenBy(q => q.Key);
    }
public IQueryable GetAllKeysWithMissingCodes()
{
var languageList=Utils.ResolveDependency().GetActive();
var localizationList=this.GetActive();
返回本地化列表
.GroupBy(q=>q.Key,(Key,items)=>newlocalizationkeywithmissingcodes()
{
键=键,
缺失代码=语言列表
.GroupJoin(
项目,
lang=>lang.Id,
loc=>loc.LanguageId,
(lang,loc)=>loc.Any()?null:lang)
.其中(q=>q!=null)
.选择(q=>q.Code)
}).OrderByDescending(q=>q.MissingCodes.Count()>0)//在顶部显示缺少的键
.ThenBy(q=>q.Key);
}

以下是用于识别缺少“完整”语言分配的键的SQL逻辑:

SELECT
    all.[Key],
    all.LanguageId
FROM
    (
    SELECT
        loc.[Key],
        lang.LanguageId
    FROM
        Language lang
    FULL OUTER JOIN
        Localization loc
        ON (1 = 1)
    WHERE
        lang.Active = 1
    ) all
LEFT JOIN
    Localization loc
    ON (loc.[Key] = all.[Key])
    AND (loc.LanguageId = all.LanguageId)
WHERE
    loc.[Key] IS NULL;
要查看所有关键点(而不是筛选),请执行以下操作:


以下是用于识别缺少“完整”语言分配的键的SQL逻辑:

SELECT
    all.[Key],
    all.LanguageId
FROM
    (
    SELECT
        loc.[Key],
        lang.LanguageId
    FROM
        Language lang
    FULL OUTER JOIN
        Localization loc
        ON (1 = 1)
    WHERE
        lang.Active = 1
    ) all
LEFT JOIN
    Localization loc
    ON (loc.[Key] = all.[Key])
    AND (loc.LanguageId = all.LanguageId)
WHERE
    loc.[Key] IS NULL;
要查看所有关键点(而不是筛选),请执行以下操作:


您的代码似乎在进行大量的数据库查询和具体化

就LINQ而言,单个查询如下

我们使用语言和本地化表的笛卡尔积来获得(键,代码)的所有组合,然后减去关系中存在的(键,代码)元组。这为我们提供了不存在的(键、代码)组合

var result = context.Languages.Join(context.Localizations, lang => true, 
loc => true, (lang, loc) => new { Key = loc.Key, Code = lang.Code })
.Except(context.Languages.Join(context.Localizations, lang => lang.Id, 
loc => loc.LanguageId, (lang, loc) => new { Key = loc.Key, Code = lang.Code }))
.GroupBy(r => r.Key).Select(r => new LocalizationKeyWithMissingCodes 
{ 
 Key = r.Key, 
 MissingCodes = r.Select(kc => kc.Code).ToList()
})
.ToList()
.OrderByDescending(lkmc => lkmc.MissingCodes.Count())
.ThenBy(lkmc => lkmc.Key).ToList();
p、 我在移动中输入了这个LINQ查询,所以如果它有语法问题,请告诉我。。
查询的要点是,我们采用笛卡尔积并减去匹配行

您的代码似乎在进行大量的数据库查询和具体化

就LINQ而言,单个查询如下

我们使用语言和本地化表的笛卡尔积来获得(键,代码)的所有组合,然后减去关系中存在的(键,代码)元组。这为我们提供了不存在的(键、代码)组合

var result = context.Languages.Join(context.Localizations, lang => true, 
loc => true, (lang, loc) => new { Key = loc.Key, Code = lang.Code })
.Except(context.Languages.Join(context.Localizations, lang => lang.Id, 
loc => loc.LanguageId, (lang, loc) => new { Key = loc.Key, Code = lang.Code }))
.GroupBy(r => r.Key).Select(r => new LocalizationKeyWithMissingCodes 
{ 
 Key = r.Key, 
 MissingCodes = r.Select(kc => kc.Code).ToList()
})
.ToList()
.OrderByDescending(lkmc => lkmc.MissingCodes.Count())
.ThenBy(lkmc => lkmc.Key).ToList();
p、 我在移动中输入了这个LINQ查询,所以如果它有语法问题,请告诉我。。
查询的要点是,我们采用笛卡尔积并减去匹配行

另一种可能性,使用LINQ:

public IEnumerable<LocalizationKeyWithMissingCodes> GetAllKeysWithMissingCodes(
    List<Language> languages,
    List<Localization> localizations)
{
    return localizations
        .GroupBy(x => x.Key, (key, items) => new LocalizationKeyWithMissingCodes
        {
            Key = key,
            MissingCodes = languages
                .GroupJoin( // check if there is one or more match for each language
                    items,
                    x => x.Id,
                    y => y.LanguageId,
                    (x, ys) => ys.Any() ? null : x)
                .Where(x => x != null) // eliminate all languages with a match
                .Select(x => x.Code) // grab the code
        })
        .Where(x => x.MissingCodes.Any()); // eliminate all complete keys 
}
public IEnumerable GetAllKeysWithMissingCodes(
列出语言,
列表(本地化)
{
返回本地化
.GroupBy(x=>x.Key,(Key,items)=>newLocalizationKeywithMissingCodes
{
键=键,
丢失代码=语言
.GroupJoin(//检查每种语言是否有一个或多个匹配项
项目,
x=>x.Id,
y=>y.LanguageId,
(x,ys)=>ys.Any()?null:x)
.Where(x=>x!=null)//使用匹配项消除所有语言
.Select(x=>x.Code)//获取代码
})
.Where(x=>x.MissingCodes.Any());//消除所有完整的键
}

另一种可能性,使用LINQ:

public IEnumerable<LocalizationKeyWithMissingCodes> GetAllKeysWithMissingCodes(
    List<Language> languages,
    List<Localization> localizations)
{
    return localizations
        .GroupBy(x => x.Key, (key, items) => new LocalizationKeyWithMissingCodes
        {
            Key = key,
            MissingCodes = languages
                .GroupJoin( // check if there is one or more match for each language
                    items,
                    x => x.Id,
                    y => y.LanguageId,
                    (x, ys) => ys.Any() ? null : x)
                .Where(x => x != null) // eliminate all languages with a match
                .Select(x => x.Code) // grab the code
        })
        .Where(x => x.MissingCodes.Any()); // eliminate all complete keys 
}
public IEnumerable GetAllKeysWithMissingCodes(
列出语言,
列表(本地化)
{
返回本地化
.GroupBy(x=>x.Key,(Key,items)=>newLocalizationKeywithMissingCodes
{
键=键,
丢失代码=语言
.GroupJoin(//检查每种语言是否有一个或多个匹配项
项目,
x=>x.Id,
y=>y.LanguageId,
(x,ys)=>ys.Any()?null:x)
.其中(x=>x!=nul