 <p>This looks to me like more of a SQL question so I will answer it accordingly. If you aren't looking for a SQL-based answer please be more clear in the question. And if you are please amend your tags.</p> <p>As long as the number of types is fixed and known, the following SQL can form your underlying SQL query (assuming the source is a SQL database):</p> <pre><code>SELECT a.StaffID, Name, CASE WHEN b.ID IS NOT NULL THEN 1 ELSE 0 END AS Type1, CASE WHEN c.ID IS NOT NULL THEN 1 ELSE 0 END AS Type2, CASE WHEN d.ID IS NOT NULL THEN 1 ELSE 0 END AS Type3 FROM dbo.Staff a LEFT JOIN dbo.StaffType b ON a.StaffID = b.StaffID AND b.TypeID = 1 LEFT JOIN dbo.StaffType c ON a.StaffID = c.StaffID AND c.TypeID = 2 LEFT JOIN dbo.StaffType d ON a.StaffID = d.StaffID AND d.TypeID = 3 </code></pre> <p>In your GridView each checkbox will know its StaffID (from the row) and TypeID (from the column) so simply handle its OnChanged event and call something like:</p> <pre><code>DECLARE @StaffID INT = 1, @TypeID INT = 1 IF EXISTS (SELECT * FROM dbo.StaffType WHERE StaffID = @StaffID AND TypeID = @TypeID) DELETE FROM dbo.StaffType WHERE StaffID = @StaffID AND TypeID = @TypeID ELSE INSERT INTO dbo.StaffType ( StaffID, TypeID ) VALUES ( @StaffID, @TypeID ) </code></pre> <p><strong>Updated with LINQ version:</strong></p> <pre><code>var q2 = from staff in staffList from type1 in typesList .Where(t =&gt; t.StaffID == staff.StaffID &amp;&amp; t.TypeID == 1) .DefaultIfEmpty() from type2 in typesList .Where(t =&gt; t.StaffID == staff.StaffID &amp;&amp; t.TypeID == 2) .DefaultIfEmpty() from type3 in typesList .Where(t =&gt; t.StaffID == staff.StaffID &amp;&amp; t.TypeID == 3) .DefaultIfEmpty() select new { StaffID = staff.StaffID, Name = staff.Name, Type1 = (type1 != null), Type2 = (type2 != null), Type3 = (type3 != null) }; </code></pre>