ASP.NET MVC Cannot Implicitly Convert Type System.Collections.Generic.List<string> to 'string' - sql

I'm trying to use EF to retrieve data from SQL and put it into a list of type viewmodel.
But when I try and retrieve the data it gives the following error: Cannot Implicitly Convert Type System.Collections.Generic.List<.string> to 'string'
I'm only trying to retrieve the ID and ProductName columns from the database.
Any help would be appreciated.
Here is my ViewModel:
public class ProductViewModel
{
public int ID { get; set; }
public string Product { get; set; }
}
Here is my controller code:
public ActionResult TableReport()
{
List<ProductViewModel> products = new List<ProductViewModel>();
ProductViewModel product = new ProductViewModel();
product.Product = db.Products.Select(z => z.ProductName).ToList();
product.ID = db.Products.Select(z => z.ProductID).ToList();
return View();
}

#GSerg: Read your code out loud. "Create an empty list of ProductViewModels. Create an empty ProductViewModel. Assign the list of all product names as the product name for that single empty ProductViewModel. Assign the list of all product ids as the id for that single empty ProductViewModel". No wonder it is not working, is it? Instead you should have done var products = db.Products.Select(z => new ProductViewModel() { ID = z.ProductID, Product = z.ProductName}).ToList();

You are putting a list in a string
Change your Viewmodel to
public class ProductViewModel
{
public int ID { get; set; }
public List<string> Product { get; set; }
}
And you are also trying to put a list in an int. That won't work either.

Related

WindowsForms-EFCore SQL Exception Invalid Column Name

I have a two table products and categories. When I add a product to products, I get an error. I share the codes.
class Products
{
public int Id { get; set; }
public string Name { get; set; }
public float Price { get; set; }
public string Description { get; set; }
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public Categories Category { get; set; }
}
With this method, I get the products. After I fill a datagridview. But I want to see categoryName instead of CategoryId. It works, I see the categoryName instead of CategoryId in datagridview.
public List<Products> GetProducts()
{
var products = context.Products.Include(x =>x.Category ).Select(m => new Products()
{
Id = m.Id,
Name = m.Name,
Price = m.Price,
Description = m.Description,
CategoryName=m.Category.Name
}).ToList();
return products;
}
After that I have an Add method
public void AddProduct(Products products )
{
context.Products.Add(products);
context.SaveChanges();
}
However, when I try to add a new product, I have an error.
The issue is that Category Name is not in the physical table, just your object. So when EF attempts to generate the SQL, it can't find a column called CategoryName.
Take a look at this question
Exclude Property on Update in Entity Framework

Model item passed does not match IEnumerable

Model:
public class Tables: DbContext
{
public IEnumerable<Thing> Thing { get; set; }
public List<Thing2> Thing2 { get; set; }
public System.Data.Entity.DbSet<Example.MainTable> MainTables { get; set; }
public System.Data.Entity.DbSet<Example.Table2> Tables2 { get; set; }
}
View:
#model IEnumerable<Example.MainTable>
Controller:
public ActionResult ABC()
{
var model = new Example.Models.Tables();
string ABC = "ABC";
model.MainTables = db.Example.Where(d => d.ColumnName.Contains(ABC)).ToList();
model.Tables2 = (from d in db.MainTables.ToList()
join j in db.Tables2.ToList() on d.AssignID equals j.ID
select new Tables2() { Name = j.Name });
List<Tables> allTables = new List<Tables>();
allTables.Add(model);
return View(allTables);
}
Error Message:
The model item passed into the dictionary is of type System.Collections.Generic.List1[Example.Models.Tables], but this dictionary requires a model item of type System.Collections.Generic.IEnumerable1[Example.MainTable].
Attempt 2 (deleted the last 2 lines before return in the controller and replaced):
return View(model);
Error Message:
The model item passed into the dictionary is of type 'Example.Models.Tables', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[Example.MainTable]'.
How do I fix this?
Either change the model on your view to #model IEnumerable<Example.Tables>
or make following changes in your controller
List<MainTable> allTables = new List<MainTable>();
allTables.Add(model.MainTables);

how to implement computed field for model in web api odata using EF 6

I'm creating a web api odata controller and all is well until I try to add a derived field to the model. I don't want the field to exist in the database, and the field does not need to be queryable.
Given model;
public class Foo
{
public Int64 Id { get; set; }
public string SomeDatabaseSourcedField{ get; set; }
public string SomeDerivedField{ get; set; }
}
If I've got a controller like;
private FooDbContext db = new FooDbContext();
[Queryable]
public IQueryable<Foo> GetFoo()
{
return db.Foo;
}
How do it set the value of SomeDerivedField?
Note: I've tried marking the field as not mapped but it seems the field does not get returned in api calls.
Here is my answer, What I'm using is odata v4. http://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/
I've successfully get the derived field in the response.
First, define a class which derives from foo:
public class MyFoo:Foo
{
public string SomeDerivedField{ get; set; }
}
Second, build the edm model:
public static IEdmModel GetModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<MyFoo>("Foo");
builder.EntityType<MyFoo>().DerivesFromNothing();
builder.Namespace = typeof(MyFoo).Namespace;
return builder.GetEdmModel();
}
Third, retrieve the data:
public IHttpActionResult Get()
{
IQueryable<MyFoo> foos= db.Foos.Select(
t => new MyFoo()
{
Id = t.Id,
Name = t.Name,
SomeDerivedField= t.Name + SqlFunctions.StringConvert((double)t.Id)
});
return Ok(foos);
}

One-to-Many relationship with ORMLite

The only examples I can find addressing this sort of scenario are pretty old, and I'm wondering what the best way is to do this with the latest version of ORMLite...
Say I have two tables (simplified):
public class Patient
{
[Alias("PatientId")]
[Autoincrement]
public int Id { get; set; }
public string Name { get; set; }
}
public class Insurance
{
[Alias("InsuranceId")]
[Autoincrement]
public int Id { get; set; }
[ForeignKey(typeof("Patient"))]
public int PatientId { get; set; }
public string Policy { get; set; }
public string Level { get; set; }
}
Patients can have multiple Insurance policies at different "levels" (primary, secondary, etc). I understand the concept of blobbing the insurance information as a Dictionary type object and adding it directly to the [Patient] POCO like this:
public class Patient
{
public Patient() {
this.Insurances = new Dictionary<string, Insurance>(); // "string" would be the Level, could be set as an Enum...
}
[Alias("PatientId")]
[Autoincrement]
public int Id { get; set; }
public string Name { get; set; }
public Dictionary<string, Insurance> Insurances { get; set; }
}
public class Insurance
{
public string Policy { get; set; }
}
...but I need the insurance information to exist in the database as a separate table for use in reporting later.
I know I can join those tables in ORMLite, or create a joined View/Stored Proc in SQL to return the data, but it will obviously return multiple rows for the same Patient.
SELECT Pat.Name, Ins.Policy, Ins.Level
FROM Patient AS Pat JOIN
Insurance AS Ins ON Pat.PatientId = Ins.PatientId
(Result)
"Johnny","ABC123","Primary"
"Johnny","987CBA","Secondary"
How can I map that into a single JSON response object?
I'd like to be able to map a GET request to "/patients/1234" to return a JSON object like:
[{
"PatientId":"1234",
"Name":"Johnny",
"Insurances":[
{"Policy":"ABC123","Level":"Primary"},
{"Policy":"987CBA","Level":"Secondary"}
]
}]
I don't have a lot of hope in this being do-able in a single query. Can it be done in two (one on the Patient table, and a second on the Insurance table)? How would the results of each query be added to the same response object in this nested fashion?
Thanks a ton for any help on this!
Update - 4/29/14
Here's where I'm at...In the "Patient" POCO, I have added the following:
public class Patient
{
[Alias("PatientId")]
[Autoincrement]
public int Id { get; set; }
public string Name { get; set; }
[Ignore]
public List<Insurance> Insurances { get; set; } // ADDED
}
Then, when I want to return a patient with multiple Insurances, I do two queries:
var patientResult = dbConn.Select<Patient>("PatientId = " + request.PatientId);
List<Insurance> insurances = new List<Insurance>();
var insuranceResults = dbConn.Select<Insurance>("PatientId = " + patientResult[0].PatientId);
foreach (patientInsurance pi in insuranceResults)
{
insurances.Add(pi);
}
patientResult[0].Insurances = insurances;
patientResult[0].Message = "Success";
return patientResult;
This works! I get nice JSON with nested items for Insurances while maintaining separate related tables in the db.
What I don't like is that this object cannot be passed back and forth to the database. That is, I can't use the same nested object to automatically insert/update both the Patient and InsurancePolicy tables at the same time. If I remove the "[Ignore]" decorator, I get a field in the Patient table called "Insurances" of type varchar(max). No good, right?
I guess I'm going to need to write some additional code for my PUT/POST methods to extract the "Insurances" node from the JSON, iterate over it, and use each Insurance object to update the database? I'm just hoping I'm not re-inventing the wheel here or doing a ton more work than is necessary.
Comments would still be appreciated! Is Mythz on? :-) Thanks...
An alternate more succinct example:
public void Put(CreatePatient request)
{
var patient = new Patient
{
Name = request.Name,
Insurances = request.Insurances.Map(x =>
new Insurance { Policy = i.Policy, Level = i.Level })
};
db.Save<Patient>(patient, references:true);
}
References are here to save the day!
public class Patient
{
[Alias("PatientId")]
[Autoincrement]
public int Id { get; set; }
public string Name { get; set; }
[Reference]
public List<Insurance> Insurances { get; set; }
}
public class Insurance
{
[Alias("InsuranceId")]
[Autoincrement]
public int Id { get; set; }
[ForeignKey(typeof("Patient"))]
public int PatientId { get; set; }
public string Policy { get; set; }
public string Level { get; set; }
}
I can then take a JSON request with a nested "Insurance" array like this:
{
"Name":"Johnny",
"Insurances":[
{"Policy":"ABC123","Level":"Primary"},
{"Policy":"987CBA","Level":"Secondary"}
]
}
...to create a new record and save it like this:
public bool Put(CreatePatient request)
{
List<Insurance> insurances = new List<Insurance>();
foreach (Insurance i in request.Insurances)
{
insurances.Add(new Insurance
{
Policy = i.Policy,
Level = i.Level
});
}
var patient = new Patient
{
Name = request.Name,
Insurances = insurances
};
db.Save<Patient>(patient, references:true);
return true;
}
Bingo! I get the new Patient record, plus 2 new records in the Insurance table with correct foreign key references back to the PatientId that was just created. This is amazing!
First you should define a foreign collection in Patient class. (with get and set methods)
#ForeignCollectionField
private Collection<Insurance> insurances;
When you query for a patient, you can get its insurances by calling getInsurances method.
To convert all into a single json object with arrays inside you can use a json processor. I use Jackson (https://github.com/FasterXML/jackson) and it works very well. Below will give you json object as a string.
new ObjectMapper().writeValueAsString(patientObject);
To correctly map foreign fields you should define jackson references. In your patient class add a managed reference.
#ForeignCollectionField
#JsonManagedReference("InsurancePatient")
private Collection<Insurance> insurances;
In your insurance class add a back reference.
#JsonBackReference("InsurancePatient")
private Patient patient;
Update:
You can use Jackson to generate objects from json string then iterate and update/create database rows.
objectMapper.readValue(jsonString, Patient.class);

Trouble loading a child model in MVC 4

I have an OrderViewModel that includes an instance of a child _DetailsViewModel. The OrderViewModel has order header information and the _DetailsViewModel holds order detail information. Despite being separate Models, both have the same single data source..the Orders table. The reason that the details are in their own View Model is that those fields are reused on a different View, in the same visual arrangement, so I'm putting them in a Partial View to be reused as needed. Here is an idea of my main and child View Models:
public class OrderViewModel
{
public string OrderNum { get; set; }
public string CustonerName{ get; set; }
public double SalesPrice{ get; set; }
public _Details Details { get; set; }
}
public class _DetailsViewModel
{
public string PhoneNum { get; set; }
public string ItemNum { get; set; }
public double Quantity { get; set; }
public string PayMethod{ get; set; }
public string Comments { get; set; }
}
Within my controller I call a service that returns all data from the Orders table and returns a List of Order Entities.
orderService = new OrderService();
var orders = orderService.GetOrderInfo(StoreNum);
From there I use Omu.ValueInjecter to inject the results into the main View Model.
var orderViewModel = orders
.Select(x => new
OrderViewModel().InjectFrom(x)).Cast<OrderViewModel>()
.ToList();
return View(orderViewModel);
I need to also populate the _Details model so that I can pass it to the Partial View from within my main Order View...like below:
#Html.Partial("_OrderDetails", Model._Details)
Is there a way to populate the _Details Model from the single service call that is already populating the main Order Model? Will I have to add the _Details properties to the main Order View and then iterate the Order view to set each field of the corresponding _Details Model manually? Surely I'm missing something.
Thanks...
Move the entities out of your database first, in that manner you only issue one query request:
// apply any filter(s) needed here.
var orderList = orders.ToList();
// then do injecting using the "cached" orders
var orderViewModel = orderList
.Select(x => new OrderViewModel().InjectFrom(x))
.Cast<OrderViewModel>()
.ToList();
// then inject into your details model
var detailsModel = orderList
.Select(x => new _DetailsViewModel().InjectFrom(x))
.Cast<_DetailsViewModel>()
.ToList();
And a small suggestion if I may, remove the underscore for _DetailsViewModel to make the naming standard.
UPDATE:
How do I add the detailsModel to the orderViewModel afterwards to pass
to the Order View?
You just simply set it to the instance of OrderViewModel like so:
orderViewModel.Details = detailsModel ;
Then return orderViewModel to your view and do your thing there:
#Html.Partial("_OrderDetails", Model.Details)