Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.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# EF Query:Give.Contains()从数据库获取信息时要处理的两个元素的组合_C#_Sql_Linq_Entity Framework 4 - Fatal编程技术网

C# EF Query:Give.Contains()从数据库获取信息时要处理的两个元素的组合

C# EF Query:Give.Contains()从数据库获取信息时要处理的两个元素的组合,c#,sql,linq,entity-framework-4,C#,Sql,Linq,Entity Framework 4,我试图优化以下方法,让它只返回程序实际计算所需的数据。在过去,数据集没有那么大,所以我不需要对其进行太多优化。最近,我的数据集从大约30k条记录增长到700k条记录,所以我正试图进一步优化它 public void readRawThresholdsInList(int inputtedESourceID, DateTime maxDateTimeVal, List<int> hashKey) { log.Info("Reading in raw th

我试图优化以下方法,让它只返回程序实际计算所需的数据。在过去,数据集没有那么大,所以我不需要对其进行太多优化。最近,我的数据集从大约30k条记录增长到700k条记录,所以我正试图进一步优化它

    public void readRawThresholdsInList(int inputtedESourceID, DateTime maxDateTimeVal, List<int> hashKey)
    {
        log.Info("Reading in raw thresholds from db");
        using (FAI db= new FAI ())
        {
            rawThresholds = (from thr in db.Thresholds
                             where thr.CalculatedDate == maxDateTimeVal
                             where thr.ErrorSourceId == inputtedESourceID
                             where hashKey.Contains(thr.HashKey)
                             select thr).ToList();
        }
        log.Info("Read in " + rawThresholds.Count() + " threshold records for error source id: " + inputtedESourceID + ".");

    }
但它因{System.NotSupportedException:无法创建“RTM_DB.HashKeyHostId”类型的常量值而出错。在此上下文中仅支持基元类型('例如Int32、String和Guid')

可能有一种非常简单的方法,我没有想到

是的,有

where hashKey.Contains(someValue) && hashKey.Contains(someOtherValue)

沿着这条路走也许就是你想做的

public void readRawThresholdsInList(int inputtedESourceID, DateTime maxDateTimeVal, List<int> hashKeys, List<int> hostIds)
{
    log.Info("Reading in raw thresholds from db");
    using (var db = new FAI())
    {
        var rths = (from thr in db.Thresholds
                    where thr.CalculatedDate == maxDateTimeVal
                    && thr.ErrorSourceId == inputtedESourceID
                    select thr);

        if (hashKeys != null && hashKeys.Count() > 0)
            rths = rths.Where(rth => hashKeys.Contains(rth.HashKey))

        if (hostIds != null && hostIds.Count() > 0)
            rths = rths.Where(rth => hostIds.Contains(rth.HostId)) // FieldName?

        rawThresholds = rths.ToList();
    }
    log.Info("Read in " + rawThresholds.Count() + " threshold records for error source id: " + inputtedESourceID + ".");
}

如果你有

List<HashKeyHostId> data = new List<HashKeyHostId>() {
    new HashKeyHostId { hashKey = 100, hostId = 1 },
    new HashKeyHostId { hashKey = 101, hostId = 5 }
}

请查看新编辑,了解我认为这不起作用的原因。@Migit我不是建议您将
hashKey
传递到两个
Contains
调用中,您可以在其中传递您想要的任何内容。我回答的要点是向您展示如何在多属性检查的上下文中使用
Contains
dit,您是否只需执行
hashKey.hashKey.Contains(thr.hashKey)&&hashKey.hostId==thr.hostId
?您的第一个hashKey是HashKeyHostId对象的列表。您不能对对象执行.contains并将其转换为SQL。要使.contains使用LINQ转换为SQL,它需要是一个原语列表。您自己创建的对象列表将出现以下错误:“无法创建“RTM_DB.HashKeyHostId”类型的常量值。在此上下文中仅支持基本类型('例如Int32、String和Guid')。@Migit抱歉,我错过了我假设的
hashKey
将是单个对象的内容。在这种情况下,检查只会变成
hashKey.Any(x=>x.hashKey.Contains(thr.hashKey))&&x.hashKey.hostId==thr.hostId))
我会试一试。在过去,我遇到了很多问题。不过,我给它提供了非常大的数据集和。有人喜欢错误地说它嵌套太深。我相信你的建议与James的建议是一样的。我认为这行不通。它需要指定哈希键和HostID的组合,而不是任何组合两者的组合。请参阅新的编辑。添加了一个解决方案,您可以在这种情况下使用,因为您的两个键都是整数。我的哈希键实际上占据了int32的全部范围,因此我无法直接使用此方法。我尝试将所有内容强制转换为双精度,但显然没有与Convert.ToDouble()等效的linq由于这是一个错误:where filter.Contains(Convert.ToDouble(thr.ParentErrorSignatureHashKey)*100000.0+Convert.ToDouble(thr.HostId))与System.NotSupportedException异常我将其更改为where filter.Contains((double)(thr.ParentErrorSignatureHashKey)*100000.0+(double)(thr.HostId))虽然这看起来确实有效,但运行时间太长。它已经运行了4分钟,但仍然没有返回。如果我在该字段中查看,它可能会运行得更快,但我会等待其他人是否有响应,然后再执行此路线。使用Int64s进行尝试,也比不使用filt花费更多时间ering.这不会因为
HashKeyHostId
无法翻译而失败吗?或者
包含的
是否做了一些其他方法没有做的聪明的事情?请参见编辑4。失败的原因与James建议的原因相同。Janne的建议听起来很棒,直到我看到运行时:(如果类型是POCO,并且您使用对象初始值设定项语法,则查询会将其理解为一个属性集合。这也可以通过匿名类型来完成。@Migit您必须使用EF,而不是linq to sql.well crap。我键入了其中的%#@*。是的,它使用的是EF
where hashKey.Contains(someValue) && hashKey.Contains(someOtherValue)
public void readRawThresholdsInList(int inputtedESourceID, DateTime maxDateTimeVal, List<int> hashKeys, List<int> hostIds)
{
    log.Info("Reading in raw thresholds from db");
    using (var db = new FAI())
    {
        var rths = (from thr in db.Thresholds
                    where thr.CalculatedDate == maxDateTimeVal
                    && thr.ErrorSourceId == inputtedESourceID
                    select thr);

        if (hashKeys != null && hashKeys.Count() > 0)
            rths = rths.Where(rth => hashKeys.Contains(rth.HashKey))

        if (hostIds != null && hostIds.Count() > 0)
            rths = rths.Where(rth => hostIds.Contains(rth.HostId)) // FieldName?

        rawThresholds = rths.ToList();
    }
    log.Info("Read in " + rawThresholds.Count() + " threshold records for error source id: " + inputtedESourceID + ".");
}
var filters = new int[] { 100 * 100 + 1 , 101 * 100 + 5 }; // 10001 & 10105

var rths = (from rth in db.Thresholds
        where rth.CalculatedDate == maxDateTimeVal
        && rth.ErrorSourceId == inputtedESourceID
            && filters.Contains(rth.HashKey * 100 + rth.HostId)
            select rth).ToList();
List<HashKeyHostId> data = new List<HashKeyHostId>() {
    new HashKeyHostId { hashKey = 100, hostId = 1 },
    new HashKeyHostId { hashKey = 101, hostId = 5 }
}
<somequery>.Where(x => data.Contains(new HashKeyHostId { hashKey = x.HashKey, hostId = x.HostId }))
WHERE ([t0].[HashKey] = @p0 AND [t0].[HostId] = @p1) OR
      ([t0].[HashKey] = @p2 AND [t0].[HostId] = @p3) OR ...