简体   繁体   中英

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.

I using this 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. 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.

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.

You may try by accepting an expression evaluating to bool in place of the Func delegate.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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