Как сделать агрегаты Linq, когда может быть пустой набор?

Если мы используем Java 7 и выше, а также знаем, какой контент будет добавлен (добавлен) в файл, мы можем использовать метод newBufferedWriter в пакете NIO.

public static void main(String[] args) {
    Path FILE_PATH = Paths.get("C:/temp", "temp.txt");
    String text = "\n Welcome to Java 8";

    //Writing to the file temp.txt
    try (BufferedWriter writer = Files.newBufferedWriter(FILE_PATH, StandardCharsets.UTF_8, StandardOpenOption.APPEND)) {
        writer.write(text);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Есть несколько замечаний:

  1. Всегда хорошая привычка указывать кодировку кодировки и для этого мы имеем константу в классе StandardCharsets.
  2. В коде используется инструкция try-with-resource, в которой ресурсы автоматически закрываются после попытки.

Хотя OP не спросил, но на всякий случай мы хотим искать строки с определенным ключевым словом, например confidential мы можем использовать потоковые API в Java:

//Reading from the file the first line which contains word "confidential"
try {
    Stream lines = Files.lines(FILE_PATH);
    Optional containsJava = lines.filter(l->l.contains("confidential")).findFirst();
    if(containsJava.isPresent()){
        System.out.println(containsJava.get());
    }
} catch (IOException e) {
    e.printStackTrace();
}

17
задан Edward Brey 12 January 2014 в 00:46
поделиться

3 ответа

Я могу воспроизвести вашу проблему с помощью следующего запроса LINQPad к Northwind:

Employees.Where(e => e.EmployeeID == -999).Sum(e => e.EmployeeID)

Здесь есть две проблемы:

  1. Sum() перегружен
  2. LINQ to SQL следует семантике SQL, а не семантике C #.

В SQL SUM(no rows) возвращает null, а не ноль. Однако вывод типа для вашего запроса дает вам decimal в качестве параметра типа вместо decimal?. Исправление состоит в том, чтобы помочь выводу типа выбрать правильный тип, то есть :

Employees.Where(e => e.EmployeeID == -999).Sum(e => (int?)e.EmployeeID)

Теперь будет использоваться корректная перегрузка Sum().

23
ответ дан Craig Stuntz 12 January 2014 в 00:46
поделиться

Если t имеет свойство типа HasValue, то я бы изменил выражение на:

var total = 
     myThings.Where(t => (t.HasValue) && (t.OtherProperty == 123)).Sum(t => t.Amount); 
-1
ответ дан DotNetWala 12 January 2014 в 00:46
поделиться

он выдает исключение, потому что результат комбинированного запроса sql равен нулю и его нельзя присвоить десятичной переменной. Если вы сделаете следующее, ваша переменная будет равна нулю (я предполагаю, что ClaimedAmount является десятичным):

var claims = Claim.Where(cl => cl.ID < 0);
var count = claims.Count(); // count=0
var sum = claims.Sum(cl => cl.ClaimedAmount as decimal?);

тогда вы должны получить желаемую функциональность.

Вы также можете выполнить ToList () в точке оператора where, и тогда сумма вернет 0, но это будет противоречить тому, что было сказано в другом месте об агрегатах LINQ.

2
ответ дан 30 November 2019 в 12:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: