Rafe
Rafe

Reputation: 7042

Different ways to populate a model in MVC C# from a LINQ query?

So as the title says, I'm trying to populate my model from LINQ. I can populate it as a LIST but are there any other ways to get data into the model? So I've got my model class:

    public class CustomersModel
    {
        public string CustomerId { get; set; }
        public string CustomerName { get; set; }
        public string PricingGroup { get; set; }
        public string PrGrId { get; set; }

    }

And I have a controller which works if I want to populate the model as a list:

public ActionResult Index(int? page)
        {            
            var content = from c in db.PCustomers
                            where c.Cust_Wholesale_Customer == -1
                            where c.Cust_Account_Status != 2
                            join csi in db.PCustomer_Sales_Info on c.Cust_Key equals csi.CustSls_Cust_Key
                            join cpg in db.PCustomer_Pricing_Groups on csi.CustSls_CustPrcGrp_Key equals cpg.CustPrcGrp_Key
                            select new { id = c.Cust_ID, cname = c.Cust_Description, pg = cpg.CustPrcGrp_Description, pgid = cpg.CustPrcGrp_Key };

            var model = new List<CustomersModel>();
            foreach (var item in content)
            {
                model.Add(new CustomersModel { CustomerId = item.id });
                model.Add(new CustomersModel { CustomerName = item.cname });
                model.Add(new CustomersModel { PricingGroup = item.pg });
                model.Add(new CustomersModel { PrGrId = item.pgid.ToString() });
            }

            return View(model);
        }

But what if I don't want this to be a list? How do I add the data to the model without specifying it as a list?

Upvotes: 0

Views: 1079

Answers (3)

jefftrotman
jefftrotman

Reputation: 1104

You could do this:

var content = from c in db.PCustomers
              where c.Cust_Wholesale_Customer == -1
              where c.Cust_Account_Status != 2
              join csi in db.PCustomer_Sales_Info on c.Cust_Key equals csi.CustSls_Cust_Key
              join cpg in db.PCustomer_Pricing_Groups on csi.CustSls_CustPrcGrp_Key equals cpg.CustPrcGrp_Key
              select new CustomersModel
              { 
                  CustomerId = c.Cust_ID, 
                  CustomerName = c.Cust_Description, 
                  PricingGroup = cpg.CustPrcGrp_Description, 
                  PrGrId = cpg.CustPrcGrp_Key 
              };

eliminating the for-each loop, although I just saw the ToString() at the end of PrGrId. I think that LinqToEntities would choke on that. Can PrGrId be whatever type cpg.custPrcGrp_Key is in the CustomersModel definition?

Your model in the view would then be a type of IEnumerable<CustomersModel>

Upvotes: 0

Jonathan
Jonathan

Reputation: 5029

Do you mean you only want one customer? If so, which one? Maybe one with a specific CustomerId? Once you have determined that, you will update your query to return one record; something like:

var id = 999; //what id you want
var customer = content.FirstOrDefault(i=>i.CustomerId == id);
if (customer == null)
    throw new NullReferenceException; // do something when you don't get the result you expect
return View(customer);

Also, you may want to look into Entity Framework. It should simplify some of your querying, because you're kind of querying, converting, and then converting again. You can do all of that in one step with Entity Framework

Upvotes: 0

Anderson Pimentel
Anderson Pimentel

Reputation: 5787

It's not clear to me, but model doesn't need to be a list. It should match the type expected in the view (declaration @model in the beggining of the Index.cshtml file).

Also, I think the code should be:

        foreach (var item in content)
        {
            model.Add(new CustomersModel { CustomerId = item.id,
                                           CustomerName = item.cname,
                                           PricingGroup = item.pg,
                                           PrGrId = item.pgid.ToString() });
        }

The original code was creating a model for each property, setting one property and leaving the others with the default values.

Upvotes: 1

Related Questions