skip to Main Content

I have these two tables one is a document, and one is a photo. So the user can add a document or a picture to the database. When retrieving the data from the database, I used a union query. This is the SQL query I used

SELECT D.* FROM Documents D
WHERE D.AddedBy = 'John'
UNION
SELECT P.* FROM Photos P
WHERE P.AddedBy = 'John'

I need to convert this to Linq.

var p = (from doc in _context.Documents
                     where doc.AddedBy == LogonUsername
                     select doc.DocumentName).Union
                     (from pho in _context.Photos
                      where pho.AddedBy == LogonUsername
                      select pho.PhotoName).ToList();

The Linq query is working fine. When I pass this to the view, it gives me this error.

The model item passed into the dictionary is of type 'System.Collections.Generic.List`1[System.String]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[Document_Management_System.Models.Document]'.

I think the model I am using is wrong.

This is the controller

public ActionResult Test()
        {
            var p = (from doc in _context.Documents
                     where doc.AddedBy == LogonUsername
                     select doc.DocumentName).Union
                     (from pho in _context.Photos
                      where pho.AddedBy == LogonUsername
                      select pho.PhotoName).ToList();
            return View(p);
        }

The view

@model IEnumerable<Document_Management_System.Models.Document>
@{
    ViewBag.Title = "Test";
}

<h2>Test</h2>

<div class="panel-body">
    <table class="zebra">
        <tr>
            <th>@Html.DisplayNameFor(model => model.DocumentName)</th>
            
        </tr>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.DocumentName)
                </td>
                
            </tr>
        }
    </table>
</div>

Please help me to figure this out. Thank you.

2

Answers


  1. You’ve done

    return View(p);
    

    And p is a List<string> (by virtue of your LINQ query having selected a single string and unioned it with another selection of a single string) but you promised the view it would receive a

    @model IEnumerable<Document_Management_System.Models.Document>
    

    A Document is not a string (is not a Document). You need to reshape your LINQ so it produces an enumerable of Document. Right now it gets a bunch of Document name (a string):

    select doc.DocumentName
    

    And a bunch of photo name..

    select pho.PhotoName
    

    and unions them together

    All in you’ll probably end up doing a Concat rather than a Union, but chiefly you probably need to adjust the query so that a Photo is transformed into a Document.. Unless of course a list of names suits your purposes 100% in which case adjust your @model declaration to promise an IEnumerable<string>

    Personally I think I’d have a whole new class, not Document, that tracked common properties between a Photo and a Document (Name? Created by user? Date uploaded? Size? Approved? Id in db?) plus an enumerable saying whether it was a photo or document (if it’s important to eg show a different icon in the Ui) and I would promise a @model that was an enumerable of that new class, call it FileViewModel or something..

    Login or Signup to reply.
  2. just fix your model and view items

    @model List<string>
    
     <th> Photo Names</th>
                
            </tr>
            @for (var i=0; i<Model.Count; i++)
            { 
                <tr>
                    <td>
                        @Html.DisplayFor(model => model[i])
                    </td>
                    
                </tr>
            }
        </table>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search