Q:

C# Trying to avoid duplicates

var multiples = from i in Enumerable.Range(min, (max - min))
                        from r in roots
                        where i % r == 0
                        select i;

For example, if roots = {2,10} it would select 20 twice. 
Is it possible to avoid duplicates here?

A:

Use the Distinct
var multiples = (from i in Enumerable.Range(min, (max - min))
                 from r in roots
                 where i % r == 0
                 select i).Distinct();

This works well on simple types like string and int. not very well on anonymous types.
In your case the i is an int, and it should therefore be ably to sort out dublicates.
EDIT
It does infact works on anonymous types (see Jeppe's comment).  because as @Jeppe said the anonymous types have a "good" Equals enabeling the Distict to determin if the to objects are equal / dublicates.

A:

You can use Any() instead of a full Cartesian join:
var multiples = from i in Enumerable.Range(min, (max - min))
                where roots.Any(r => i % r == 0)
                select i;

This has the added advantage that it will stop testing elements in roots as soon as it finds one that succeeds, and it does not require a second pass through to pull out the distinct elements.

A:

Use DISTINCT
var multiples = (from i in Enumerable.Range(min, (max - min))
                        from r in roots
                        where i % r == 0
                        select i).Distinct();

