简体   繁体   English

LINQ 表达式 'FirstOrDefault()' 无法翻译,将在本地求值

[英]The LINQ expression 'FirstOrDefault()' could not be translated and will be evaluated locally

In seeding, I use collection of jsons to read it and insert in DB.在播种中,我使用 jsons 集合来读取它并插入到数据库中。

I using this function我用这个 function

private void Seed<T, T2>(DbSet<T> dataSet, Func<T, T2> uniquProperty) where T : class, ISeedableEntity<T>
{
    var separtor = Path.DirectorySeparatorChar;
    var tableName = Model.FindEntityType(typeof(T)).SqlServer().TableName;
    var baseDir = Assembly.GetExecutingAssembly().Location;
    baseDir = Path.GetDirectoryName(baseDir);
    var filePath = $"{baseDir}{separtor}Data{separtor}{tableName}.json";
    if (File.Exists(filePath))
    {
        var data = File.ReadAllText(filePath);
        var items = JsonConvert.DeserializeObject<List<T>>(data);
        foreach (var item in items)
        {
            var found = dataSet.Where(
                a => uniquProperty(a).Equals(uniquProperty(item))).FirstOrDefault();

            if (found != null)
            {
                found = found.Update(item);
                dataSet.Update(found);
            }
            else
                dataSet.Add(item);
        }
        SaveChanges();
    }
}

And call it as this code.并将其称为此代码。

Seed(CreditRatings, a => a.Id);

The problem (I believe) is in the uniqueProperty delegate, which is declared as a Func delegate.问题(我相信)出在uniqueProperty委托中,它被声明为Func委托。 LINQ cannot translate compiled functions into parts of the SQL instruction, and therefore gives up the effort, letting the predicate resolve at the calling end. LINQ 无法将编译后的函数翻译成 SQL 指令的一部分,因此放弃努力,让谓词在调用端解析。

The direct result of such unfortunate even is that all the data from the database would be transferred to the caller prior to subduing them to the function.这种不幸的直接结果甚至是,在将他们制服到 function 之前,数据库中的所有数据将被传输给调用者。

You may try by accepting an expression evaluating to bool in place of the Func delegate.您可以尝试接受评估为bool的表达式来代替Func委托。

private void Seed<T, T2>(DbSet<T> dataSet, Expression<Func<T, T, bool>> predicate)
where T : class, ISeedableEntity<T>
{
    // ...
}

The predicate would have to complete comparison of unique properties:谓词必须完成唯一属性的比较:

Expression<Func<T, T, bool>> seed = (a, b) => a.Id.Equals(b.Id);

It is probably possible to incorporate an expression which isolates an equatable property as well, and then to perform the equality test directly in the Where clause, but that would require a bit more work.也可以合并一个隔离可等式属性的表达式,然后直接在Where子句中执行相等性测试,但这需要更多的工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM