Entity Framework: Select field name causing error - asp.net-mvc

The moment I mention field names when fetching data from db, I start getting errors.
Before my code was this and it was working:
var customer = from s in db.Customers
select s;
The moment I change it to:
var customer = (from s in db.Customers
select new
{
CompanyName = s.CompanyName,
ContactName = s.ContactName,
ContactTitle = s.ContactTitle,
Address = s.Address,
});
I start getting error as follows:
The model item passed into the dictionary is of type
'PagedList.PagedList1[<>f__AnonymousType24[System.String,System.String,System.String,System.String]]',
but this dictionary requires a model item of type
'PagedList.IPagedList`1[MVCCRUDPageList.Models.Customer]'.
My view looks like:
#model PagedList.IPagedList<MVCCRUDPageList.Models.Customer>
#using PagedList.Mvc;

This error is caused because you are not sending the Customer model to the view.
By doing select new { ... } you are creating an anonymous object.
You may consider changing your code to:
select new MVCCRUDPageList.Models.Customer
{
CompanyName = s.CompanyName,
ContactName = s.ContactName,
ContactTitle = s.ContactTitle,
Address = s.Address,
}
You may still need to convert the IQueryable to IPagedList

The error is telling you that the view is expecting one type but you are passing it another type. The Linq Select method you have is projecting to an anonymous type instead of the expected Customer class. Change your code to match, something like this
var customer = (from s in db.Customers
select new Customer //<--- This here, you may need to use
// the full namespace MVCCRUDPageList.Models
{
CompanyName = s.CompanyName,
ContactName = s.ContactName,
ContactTitle = s.ContactTitle,
Address = s.Address,
});

Related

Dynamic table names in Entity Framework linq

I'm using Entity Framework 6 with ASP.Net MVC 5. When using a database context object, is there a way to use a variable for the table name, without having to manually write the query?
For example:
var tableName = "NameOfTable";
result = context.tableName.Find(...);
I know that particular code won't work, because tableName is not defined in context, but is there a way to achieve the desired effect?
There are some similar questions on this site, but they never really solved the problem and they were for earlier versions of entity framework, so I'm hoping that there is an answer now.
Here's a simple solution using a switch to associate a particular Type to a table. You could also maintain use some sort of Dictionary<string, Type> object.
var tableName = "Table1";
// Get proper return type.
Type returnType;
switch(tableName) {
case "Table1":
returnType = typeof(Table1EntityType);
break;
case "Table2":
returnType = typeof(Table2EntityType);
break;
}
var query = context.Set(returnType);
// Filter against "query" variable below...
var result = query.Where(...);
-or-
var tableName = "Table1";
Dictionary<string, Type> tableTypeDict = new Dictionary<string, Type>()
{
{ "Table1", Table1Type },
{ "Table2", Table2Type }
};
var query = context.Set(tableTypeDict[tableName]);
// Filter against "query" variable below...
var result = query.Where(...);
EDIT: Modified for Entity Framework
EDIT2: Use typeof per #thepirat000 's suggestion
In addition to the helpful answers above, I also want to add this in case it helps someone else.
If you are getting this error on the "Where" clause in Mark's answer:
'DbSet does not contain a definition for 'Where' and no acceptable extension method 'Where' accepting an argument of the type 'DbSet' could be found.
Installing the Nuget Package "System.Linq.Dynamic.Core" made the error disappear for us.
If you need to access the LINQ methods and the column names from the table, you can code something like this:
var tableName = "MyTableName";
var tableClassNameSpace = "MyProject.Models.EntityModels";
using (var dbContext = new MyEntities())
{
var tableClassName = $"{tableClassNameSpace}.{tableName}";
var dynamicTableType = Type.GetType(tableClassName); // Type
var dynamicTable = dbContext.Set(dynamicTableType); // DbSet
var records = dynamicTable
.AsQueryable()
.ToDynamicList()
.OrderBy(d => d.MyColumnName)
.Select(d => new { d.MyColumnName })
.ToList();
// do stuff
}

Fetching details on an entity in Breeze using Employee('1234')

I want fetch the details of a Collection in Odata services like the following URL
http://my.company.com/odata/Employee('1234')/Details
I tried with the following code to do so. Not sure whether fromEntityKey is the right thing to do or anything else.
manager = new breeze.EntityManager(collectionData.serviceName);
var empType = manager.metadataStore.getEntityType("Employees");
var entityKey = new EntityKey(empType, '1234');
var query = EntityQuery.fromEntityKey(entityKey);
But it gives me an error "Be sure to execute a query or call fetchMetadata first."
I also tried that from this link. But I'm still getting the same.
Can any one help me on this?
You can't use manager.metadataSote.getEntityType("Employees") until metadata has been retrieved from the server. By default this occurs during the first query operation, but your code is attempting to use the metadata before it has been retrieved.
Also, I think that you are confusing the name of your resource "Employees" with the type of the instances returned by your resource, probably "Employee". I would also check whether your key's datatype is numeric or a string. The example below assume its numeric (unlike your example where the datatype of the key is presumably a string because you are quoting it).
So you have two approaches, either force the metadata to be fetched before you compose your query, like this:
manager = new breeze.EntityManager(serviceName);
manager.fetchMetadata().then(function () {
var empType = manager.metadataStore.getEntityType("Employee");
var entityKey = new EntityKey(empType, 1);
var query = EntityQuery.fromEntityKey(entityKey);
// if you want to also see the queries details
query = query.expand("Details");
return manager.executeQuery(query);
}).then(function (data) {
var results = data.results;
ok(results.length === 1, "should have returned a single record");
var emp = results[0];
));
or if you know the string name of the 'key' ("Id" in the example below) field, use it directly
manager = new breeze.EntityManager(serviceName);
var query = EntityQuery.from("Employees")
.where("Id", "==", 1)
.expand("Details");
manager.executeQuery(query).then(function(data) {
var results = data.results;
var emp = results[0];
});

Dart: How to bind to variables annotated with int via Web UI?

What is the best practice in Dart when dealing with classes as data records?
To Elaborate: When writing an app, it is likely that a class for a table row will be created. As in
class Item { int itemid, String itemName, double score }
Item item = new Item();
This allows compile time catching of any typos etc. in Dart. (Unlike using a class that relies on NoSuchMethod.)
It will also need a corresponding string structure to bind to the HTML such as
<input id="itemname" type="text" bind-value="itemEdit.itemName">
So the Dart would be:
class ItemEdit { String itemId, String itemName, String score }
ItemEdit itemEdit = new ItemEdit();
Next we need a way to get from one to the other, so we add a method to Item
fromStrings(ItemEdit ie) {
itemid = ie.itemId == null ? null : int.parse(ie.itemId);
itemName = ie.ItemName;
score = ie.score == null ? null : double.parse(ie.score);
}
And the other way around:
toStrings(ItemEdit ie) {
ie.itemid = itemId == null ? '' : ie.itemId.toString();
ie. itemName = itemName == null ? '' : itemname; // Web_ui objects to nulls
ie.score = score == null ? null : score.toStringAsFixed(2);
}
Also, we get jason data from a database, so we need to add another method to Item:
fromJson(final String j) {
Map v = JSON.parse(j);
itemid = v['itemid'];
itemname = v['itemname'];
score = v['score'];
}
And we need to be able to revert to default values:
setDefaults() { itemId = 0; itemName = "New item"; score = 0; }
This verbosity gets me feeling like I am writing COBOL again!
There is something fundamental missing here - either in my understanding, or in the Dart/WebUI libraries.
What I would like to write is something like
class Item extends DataRecord {
int itemid = 0,
String itemName = 'New item',
double score = 0.0;
}
Then, without further coding, to be able to write code such as
item.toStrings();
...
item.fromStrings();
...
item.fromJson(json);
...
item.setDefaults(); // results in {0,'New item',0.0}
And to be able to write in the HTML:
value="{{item.strings.score}}"
If this was possible, it would be quicker, simpler, clearer, and less error prone than the code I am writing at the moment.
(Full disclosure, this answer is written with the assumption that at least one bug will be fixed. See below)
Three suggestions that might help.
Use named constructors to parse and create objects.
Take advantage of toJson() when encoding to JSON.
Use bind-value-as-number from Web UI
1) Named constructors
import 'dart:json' as json;
class Item {
int itemid;
String itemName;
double score;
Item.fromJson(String json) {
Map data = json.parse(json);
itemid = data['itemid'];
itemName = data['itemName'];
score = data['score'];
}
}
2) Encoding to JSON
The dart:json library has a stringify function to turn an object into a JSON string. If the algorithm encounters an object that is not a string, null, number, boolean, or collection of those, it will call toJson() on that object and expect something that is JSON-encodable.
class Item {
int itemid;
String itemName;
double score;
Map toJson() {
return {'itemid':itemid, 'itemName':itemName, 'score':score};
}
}
3) Now, having said that, sounds like you want to easily bind to HTML fields and get primitive values back, not just strings. Try this:
<input type="number" min="1" bind-value-as-number="myInt" />
(Note, there seems to be a bug with this functionality. See https://github.com/dart-lang/web-ui/issues/317)
(from https://groups.google.com/a/dartlang.org/forum/#!topic/web-ui/8JEAA5OxJOc)
Just found a way to perhaps help a little in the this situation:
class obj {
int gapX;
String get gapXStr => gapX.toString();
set gapXStr(String s) => gapX = int.Parse(s);
...
Now, from the HTML you can use, for example
bind-value="gapXStr"
and in code you can use
x += ob.gapX;

How to parse multiple nodes of html using HtmlAgilityPack?

I'd appreciate if someone could help! I'm trying to parse the following page of Groupon website http://www.groupon.com/browse/chicago?category=activities-and-nightlife
var webGet = new HtmlWeb();
var deal1 = webGet.Load("http://www.groupon.com/browse/chicago?category=activities-and-nightlife");
I want to get the whole block of each Deal(i.e. offer for discount)
HtmlNodeCollection content_block = deal1.DocumentNode.SelectNodes("//div[#class = 'deal-list-tile grid_5_third']");
Then out of each block i want to get title, company name, location and price.
foreach(HtmlNode node in content_block)
{
string title2 = node.SelectSingleNode("//div[#class = 'deal-title js-permalink']").InnerText;
string country2 = node.SelectSingleNode("//p[#class = 'merchant-name']").InnerText;
string location2 = node.SelectSingleNode("//p[#class = 'location']").InnerText;
string price2 = node.SelectSingleNode("//div[#class = 'price']/span").InnerText;
}
Here i get confused, i need to write all the information about deals into
DbSet<Deal> Deals , but even if i try to display the content as ViewBag.Message = title + country + location + price; i get System.NullReferenceException: Object reference not set to an instance of an object in the line with content_block.
What am i doing wrong =(
Thanks in advance!
The problem appears to be that the selectnodes returns nothing or null when no nodes are found instead of an empty collection. so this means you should probably wrap if (content_block != null) { around your code block above.

handling null values in linq to sql

i have to handle exception in my query when assigning values in view model ie i have set the values in view model when any value is null it is not showing other fields of my table showing error object reference error how to handle this error in my query
my code is as follows-
var query = (from results in db.Resumes
where results.ResumeID == ResumeID && results.User.UserID == uid
select results).ToList().Select(results=>new ResumewizardPreviewmodel
{
Resumetitle = results.ResumeTitle??"",
DesiredJob = results.DesiredJob??"",
Objective = results.Objective??"",
DesiredCompany = results.DesiredCompany??"",
DesiredSalary = results.DesiredSalary.ToString(),
Salarytype = results.SalaryType,
additionalinfo = results.AdditionalInfo,
res_url = results.Res_URL,
visa = results.Visa.ToString()??"0",
TelecommuteType = results.TelecommuteType.Description,
RelocationType = results.RelocationType.Description,
isactive = results.IsActive,
isConfidential = results.isConfidential
}).SingleOrDefault();
You can use a tool like AutoMapper to convert one entity to another.
Here is an example of converting collections and null value substitution.

Resources