Only primitive types ('such as Int32, String,

2019-09-07 07:57发布

问题:

I am having some trouble with a linq query I am trying to write.

I am trying to use the repository pattern without to much luck. Basically I have a list of transactions and a 2nd list which contains the description field that maps against a field in my case StoreItemID

    public static IList<TransactionViewModel> All()
    {
        var result = (IList<TransactionViewModel>)HttpContext.Current.Session["Transactions"];
        if (result == null)
        {
            var rewardTypes = BusinessItemRepository.GetItemTypes(StoreID);
            HttpContext.Current.Session["Transactions"] = 
                result =
              (from item in new MyEntities().TransactionEntries
                 select new TransactionViewModel()
                                   {
                            ItemDescription = itemTypes.FirstOrDefault(r=>r.StoreItemID==item.StoreItemID).ItemDescription,
                     TransactionDate = item.PurchaseDate.Value,
                     TransactionAmount = item.TransactionAmount.Value,
                                   }).ToList();
        }
        return result;
    }


     public static List<BusinessItemViewModel>GetItemTypes(int storeID)
    {
        var result = (List<BusinessItemViewModel>)HttpContext.Current.Session["ItemTypes"];
        if (result == null)
        {
            HttpContext.Current.Session["ItemTypes"] = result =
                (from items in new MyEntities().StoreItems
                 where items.IsDeleted == false && items.StoreID == storeID
                 select new BusinessItemViewModel()
                 {
                     ItemDescription = items.Description,
                     StoreID = items.StoreID,
                     StoreItemID = items.StoreItemID
                 }).ToList();
        }
        return result;

However I get this error

Unable to create a constant value of type 'MyMVC.ViewModels.BusinessItemViewModel'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.

I know its this line of code as if I comment it out it works ok

ItemDescription = itemTypes.FirstOrDefault(r=>r.StoreItemID==item.StoreItemID).ItemDescription,

How can I map ItemDescription against my list of itemTypes?

Any help would be great :)

回答1:

This line has a problem:

 ItemDescription = itemTypes.FirstOrDefault(r=>r.StoreItemID==item.StoreItemID)
                            .ItemDescription,

Since you are using FirstOrDefault you will get null as default value for a reference type if there is no item that satifies the condition, then you'd get an exception when trying to access ItemDescription - either use First() if there always will be at least one match or check and define a default property value for ItemDescription to use if there is none:

 ItemDescription = itemTypes.Any(r=>r.StoreItemID==item.StoreItemID) 
                           ? itemTypes.First(r=>r.StoreItemID==item.StoreItemID)
                                      .ItemDescription
                           : "My Default",


回答2:

If itemTypes is IEnumerable then it can't be used in your query (which is what the error message is telling you), because the query provider doesn't know what to do with it. So assuming the that itemTypes is based on a table in the same db as TransactionEntities, then you can use a join to achieve the same goal:

using (var entities = new MyEntities())
{
    HttpContext.Current.Session["Transactions"] = result =
                (from item in new entities.TransactionEntries
                 join itemType in entities.ItemTypes on item.StoreItemID equals itemType.StoreItemID
                 select new TransactionViewModel()
                 {
                     ItemDescription = itemType.ItemDescription,
                     TransactionDate = item.PurchaseDate.Value,
                     TransactionAmount = item.TransactionAmount.Value,
                     CustomerName = rewards.CardID//TODO: Get customer name

                 }).ToList();
}

I don't know the structure of your database, but hopefully you get the idea.



回答3:

I had this error due a nullable integer in my LINQ query. Adding a check within my query it solved my problem.

query with problem:

var x = entities.MyObjects.FirstOrDefault(s => s.Obj_Id.Equals(y.OBJ_ID));

query with problem solved:

var x = entities.MyObjects.FirstOrDefault(s => s.Obj_Id.HasValue && s.Obj_Id.Value.Equals(y.OBJ_ID));