I am developing a web application where in i have a WCF service which interacts with the database using entity framework. I want to get rid of creating Classes for each & every LINQ query
e.g
public class Emp
{
public int CD{get;set;}
public string Name{get;set;}
}
public List<Emp> GetServTypeForPromotionDue()
{
return (from a in Context.TableName
select new Emp{ a.CD, a.NAME });
}
for other table & LINQ i have to create a separate class every time. Alternative to this is to use Anonymous method which is not preferable solution. To avoid both the methods I am using Tuple Class where I return List> or List> depending on the return type. This works fine but the problem is I am binding the result of LINQ query directly to a Gridview By default Tuple has properties item1,item2,..& so on. So my griview shows these names are column names so, Is there any way I can change the property name to CD, Name instead of Tuple's Item1, Item2 before binding to grid?
when binding the list, you could use linq:
this.grid.DataSource = tupleList.Select(i => new
{
FirstName = i.Item1,
LastName = i.Item2,
CD = i.Item3
});
You would have to change the column names on the GridView and not the tuple. A tuple is a lightweight type that doesn't support much customization (MSDN). If you know what you are binding to the GridView, change the column names by handling the RowDataBound event and checking the RowType of Header, then changing the column names there.
Related
We are using Spring MVC 4.1.2 and Spring Data JPA 1.9.0. Everything works fine but when we have custom query with only selected field for a given entity then our json response does not include property name in the response, instead it just included property value.
If I correctly guess, your custom query looks like:
SELECT e.myProperty FROM Entity e [WHERE ...]
The effect of this is that you get a List<Object[]> containing only the array of property values instead of an object that has a field with the name myProperty and its value is the value in the database.
The solution is to create a custom data-transfer object, which has this one field and assign the value in the constructor
public class MyPropertyDTO { // find a better name, though :)
private int myProperty;
public MyPropertyDTO(int myProperty) {
this.myProperty = myProperty;
}
public int getMyProperty() {
return myProperty;
}
}
Then rewrite your query as:
SELECT NEW com.mycompany.MyPropertyDTO(e.myProperty) FROM Entity e [WHERE ...]
In theory you could even use your original Entity class, add a json view on myProperty and create the matching constructor instead of creating a brand new class.
I am trying to pass a 2nd List of objects from the Controller to the
View via the ViewBag
Here is the line from my controller code.
ViewBag.FeaturedProductList = await Service.SendAsync(new ProductQuery());
The return object is the following
public class FeaturedProductListDto : IDto
{
public IEnumerable<FeaturedProductDto> Contents { get; set; }
}
In the View, I need to do a linq to select from the
ViewBag.ViewBag.FeaturedProductList in the following line.
#foreach (var productGroup in ViewBag.FeaturedProductList.Select((e,
i) => new {Product = e, Grouping = (i/3)}).GroupBy(e => e.Grouping))
{
}
I need to group the number of items from the list in sets of 3 but the
Select is throwing an error as the following
Cannot use a lambda expression as an argument to a dynamically
dispatched operation without first casting it to a delegate or
expression tree type.
I used the same code for my other List which I passed in as the Model
and it works.
This line works. #foreach (var productGroup in Model.Select((e, i) =>
new { Product = e, Grouping = (i / 4) }).GroupBy(e => e.Grouping))
Do I need to recast the ViewBag.FeaturedProductList? What is the fix
for this? Any help is greatly appreciated. Thanks.
ViewBag is a dynamic dictionary. Items in this dictionary are of type dynamic. You cannot use LINQ methods on that.
You need to cast ViewBag.FeaturedProductList to FeaturedProductListDto type and use the Contents property which is a collection type on which we can apply LINQ extension methods.
#foreach (var item in ((FeaturedProductListDto) ViewBag.FeaturedProductList).Contents
.Select(//your existing select code goes here))
{
}
I am not quite sure what you are trying to do with the GroupBy inside your Select. My personal preference is doing all such things in the action method/another layer which provides data to the action method and keep the razor markup with minimal C# code, and with more HTML markup for the page. :)
I recently started working with ServiceStack and its ORMLite framework. I have searched on Google and browsed the source code but couldn't find anything relevent.
Is there any way to select specific columns when executing a query with ORMLite ?
Something like that : Db.First<Model>(q => q.Id == someId, "Column1, Column2")
Unless I missed this feature, I am surprised nobody asked about this before, since this is one the rule of thumbs to optimize your DB transactions.
If you want to specify columns other that the table you need to use SQL as seen in this earlier example
So in your case you could do something like:
Db.First<Model>("SELECT Column1, Column2 FROM AnyTableOrView");
You can also create a partial model that looks at your table by decorating it with the [Alias] attribute, like:
[Alias("AnyTableOrView")]
public class Model {
public int Id { get; set; }
public string Column1 { get; set; }
public string Column2 { get; set; }
}
Then you can do something like:
Db.First<Model>(q => q.Id == someId);
And it will only SELECT + populate fields from the partial model.
I did try this :
Created a Database VIEW (table name and columns are already set)
Created a class named "Event" and matching each fields for that table with a property
(i used [Alias] for table name and for all columns to have nice names)
Wrote access to DB to select 1 record based on it's ID
var dbFactory = new OrmLiteConnectionFactory(
"Data Source=MyDB;User Id=user;Password=pwd", // Connection String
OracleDialect.Provider);
using (var db = dbFactory.OpenDbConnection())
{
var event = db.GetByIdOrDefault<Event>( request.Id );
}
At that point the var 'event' is populated but only the Id field is filled !
all the others fields of the class are not filled (while there are really data in database).
It's the simplest i can do and it does not work. Any ideas ?
(PS : i am using OrmLite for Oracle)
Thanks
I have found the problem.
It was due to an incorrect type matching between field in my class (defined as a string) and the corresponding Oracle Field (that is a DATE).
I replaced the string with datetime and worked like a charm.
So it's working perfectly with a VIEW and that's GREATLY simplify the code.
I had a similar problem, however my solution was different.
I had a int property in my POCO. My query (from Oracle) was returning a null for this property. It caused a exception to be raised and prevented further processing of that row.
The result was a partial populated POCO.
The solution was to change to type to be nullable.
public int? mypropperty
There are a few posts about this, but after hours of searching I still can't find what I need.
The answer in the following post almost gets me what I want:
Combobox for Foreign Key in DataGridView
Question 1:
Going off that example where a Product has many Licenses, my database mappings are all many-to-one relationships which means my License class holds a reference to the Product class. The License class does not have a property for the ProductId since that can be retrieved via the Product reference. I don't want to muck up the License class with both a reference to Product and a ProductId property just to make binding in the UI easier.
Because of this I can't set the DataPropertyName to an Id field. It needs to be the class reference name like so:
DataGridViewComboBoxColumn dataGridViewComboBoxColumn =
(DataGridViewComboBoxColumn)myDataGridView.Columns("LicenseComboBoxColumn");
dataGridViewComboBoxColumn.DataPropertyName = "License"; // not LicenseID
****Update****
I was able to get this to partially work without creating the ProductId property by specifying the Product.Id as the DataPropertyName like so:
dataGridViewComboBoxColumn.DataPropertyName = "License.Id";
However, when doing so, it broke databinding which caused me to manually get and set the cell value.
I've also seen posts about binding to the DataGridView cell, but databinding breaks when I do that and the datasource itself is never updated:
// populate the combo box with Products for each License
foreach (DataGridViewRow row in myDataGridViewProducts.Rows)
{
IProduct myProduct = row.DataBoundItem as IProduct;
DataGridViewComboBoxCell cell = (DataGridViewComboBoxCell)row.Cells("myProductCol");
cell.DataSource = getListOfILicenseObjectsFromDao(myProduct.Id);
cell.Value = myProduct.License.Id;
}
Maybe I'm doing something wrong, or maybe there's a different way. Can anyone help here?
Question 2:
How do I display a different list of Licenses for each Product?
In other words, the combobox list of Licenses will be different for each Product in the grid. I'd like to do this using databinding so I don't have to get and set the values myself.
I found the answer myself. I had this same issue a while ago and found the solution in some old code I dug up. The solution was to add a Self property to the object I wanted to databind to in the combobox (in the example above it would be the License class) and use that property as the ValueMember like so:
foreach (DataGridViewRow row in myDataGridViewProducts.Rows)
{
IProduct myProduct = row.DataBoundItem as IProduct;
DataGridViewComboBoxCell cell = (DataGridViewComboBoxCell)row.Cells("myProductCol");
cell.DataSource = getListOfILicenseObjectsFromDao(myProduct.Id);
cell.DataPropertyName = "License";
cell.DisplayMember = "Name";
cell.ValueMember = "Self"; // key to getting the databinding to work
// no need to set cell.Value anymore!
}
The License class now looks like this:
Public class License
{
public string Name
{
get; set;
}
public ILicense Self
{
get { return this; }
}
// ... more properties
}
Granted I had to "muck" up the Business classes with a property named Self, but that's much better (less confusing to the programmer) than having both a reference to License and a LicenseId property in the Product class IMO. Plus it keeps the UI code much much simpler as there's no need to manually get and set the values - just databind and done.
private List<Tuple<int, string>> GetEmpDetails()
{
return (from r in dataContext.Emp
select new Tuple<int, string>(r.ID, r.Name)).ToList();
}
I am returing a list of Tuple from WCF Service & Binding to a gridview
But when i bind it to a GridView It shows header as Item1 & Item2. Is there any way I can change the Tuple Property Names
you can't it's a tuple, this is the meaning of tuple, some values attached.
And it wasn't created for this abuse you're doing with it, you shouldn't bind a tuple to ui.
create a presentation model and bind him.