Take a desired string, iterate through objects to see if it exists in a given field and append a number until a unique string is found
There's certainly room for improvement.


Move that that Select(stringFieldFunction).ToList() out of the while loop. Iterating an IEnumerable might be quite expensive, and there's no need to repeat that work when you find a duplicate.
Select only those strings that have originalString as a prefix. That will reduce the amount of items you need to check against when adjusting the suffix.
Instead of making a list, turn those results into a (hash)set, for faster lookup.


Regarding EF complaining: apparently it doesn't support those StringComparsion overloads, so it'll have to fetch all rows from the database and run your Any predicate in memory, which may be slower as expected. Maybe an alternative approach like using ToUpperInvariant can be translated to SQL?



Applying the above changes will give you the following:

private string GetUniqueValue&lt;T&gt;(string value, IEnumerable&lt;T&gt; items, Func&lt;T, string&gt; getValue)
{
    var possibleDuplicates = items
        .Select(getValue)
        .Where(val =&gt; val.StartsWith(value, StringComparison.InvariantCultureIgnoreCase))
        .ToHashSet();

    var result = value;
    var suffix = 1;
    while (possibleDuplicates.Contains(result))
    {
        result = value + "_" + suffix;
        suffix += 1;
    }
    return result;
}




Addendum

As t3chb0t and ErikE already pointed out, if you want the benefits of Linq-to-SQL, then you need to use IQueryable&lt;T&gt;. Not only that, you also need to make sure that you're using the Queryable Linq extension methods, not the Enumerable variants.

The difference is that Enumerable methods have Func&lt;&gt; parameters, while the Queryable variants have Expression&lt;Func&lt;&gt;&gt; parameters. An Expression is a data structure that represents a piece of code, which makes translation to SQL possible. Because stringFieldFunction is a Func, not an Expression&lt;Func&gt;, the Enumerable.Select variant is used. That cannot be translated to SQL, so all data has to be loaded from the database before the Select (and any subsequent operation) can be performed on it.

To recap: use IQuerable&lt;T&gt;, make sure you're using Queryable Linq methods, and only use supported methods within your expressions.