Server Error due to paging issue - asp.net

I think I sorted out my GridView1_PageIndexChanged event and thinking it should work
protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
GridView1.DataSourceID = "lqPackWeights";
GridView1.PageIndex = e.NewPageIndex;
}
However, when I now attempt to access page 2 of x, I receive the following:
Server Error in '/project' application.
This provider supports Skip() only over ordered queries returning entities or projections that contain all identity columns, where the query is a single-table (non-join) query, or is a Distinct, Except, Intersect, or Union (not Concat) operation.
I'm a bit confused by this, I'm not using skip as far as I can see unless I am going blind?
I am currently using SQL2000, is this a problem directly related to this instance of SQL?

Are you using LINQ to SQL? The problem seems unique to SQL Server 2000. See these MSDN articles on Troubleshooting (LINQ to SQL) and Standard Query Operator Translation (LINQ to SQL) for more information.
EDIT
A similiar question has been asked before, see: LINQ, Skip, OrderBy, and SQL Server 2000

The control is using Skip to get to the records for the specific page that it is supposed to display.
In SQL Server there is no default ordering for queries (unless it's a direct table with a clustered index), so you have to specify an order in the query for the data source. The result of the query has to have a specific ordering; it doesn't make sense to page through a result if the ordering changes from page to page so that you get more or less a random pick of records from the result for each page.

Currently my linq query is ordered...I guess that is not the way forward or am I misunderstanding you?
private object GetMaterialData(string MemberKey, string MaterialType, string MaterialLevel, int Count)
{
ORWeightsDataClassesDataContext db = newORWeightsDataClassesDataContext();
var query = db.tblOnlineReportingCOMPLETEWeights
.Where(x => x.MaterialLevel == MaterialLevel && x.MaterialText == MaterialType && x.MemberId == MemberKey)
.OrderByDescending(x => x.ProductPercentage).Take(Count);
return query;
}

Related

NHibernate: adding calculated field to query results

I have inherited an ASP.NET website built on NHibernate, with which I have no experience. I need to add a calculated field based on a column in a related table to an existing query. In SQL, this would be done easily enough using a correlated subquery:
select
field1,
field2,
(select count(field3) from table2 where table2.table1ID = table1.ID) calc_field
from
table1
where
[criteria...]
Unfortunately, of course, I can't use SQL for this. So in reality, I have three related questions:
What is the best way to trace through the web of interfaces, base classes, etc used by NHibernate in order to pinpoint the object where I need to add the field?
Having located that object, what, if anything, has to be done besides adding a public property to the object corresponding to the new field?
Are there any NHibernate-specific considerations with regard to referencing a related object in a query?
Here is the existing code that performs the search:
public INHibernateQueryable<C> Search(ISearchQuery query, string sortField)
{
_session = GetSession();
var c = _session.Linq<C>();
c.Expand("IP");
c.Expand("LL");
c.Expand("LL.Address");
c.Expand("LL.Address.City");
c.Expand("LL.Address.City.State");
c.Expand("LL.Address.City.County");
c.Expand("CE");
c.Expand("IC");
c.Expand("AR");
c.Expand("ER");
c.Expand("Status");
var res = _SearchFilters
.Where(x => x.ShouldApply(query))
.Aggregate(c, (candidates, filter) => (INHibernateQueryable<C>) filter.Filter(candidates, query));
res = SortSearch(res, sortField);
return res;
}
I appreciate any advice from experienced Hibernators.
Thanks,
Mike
If you are only interested in returning a query containing a computed value, you can still call a stored procedure in NHibernate and map the results to a POCO in the same way as you map a table for CRUD operations; obviously read-only instead of updatable.
Have a look at the ISession.CreateSQLQuery method; I can post an example from one of my projects if you need one.

How to retrieve data with offset and limit using webservice request?

I am trying to build an AX service to retrieve data from InventTable in Microsoft Dynamics AX 2009.
With reference to https://community.dynamics.com/ax/f/33/t/70476.aspx ,I tried to execute a code in AOT Job for retrieving data with modifieddate="2/7/2013"
The code sample is as below:
static void SelectQueryTest(Args _args)
{
Query q = new Query();
QueryRun qr;
QueryBuildDataSource qbds;
int64 countItem;
InventTable inventTable;
Fromdate FromDate = 2\7\2013;
;
qbds = q.addDataSource(tableNum(InventTable));
qbds.addRange(fieldNum(InventTable, modifiedDateTime)).value(date2StrUsr(FromDate ));
qr = new QueryRun(q);
countItem =SysQuery::countTotal(qr);
if(countItem>0)
{
while(qr.next())
{
inventTable = qr.get(tableNum(inventTable));
info(strfmt("Item Name: %1", inventTable.ItemName));
}
}
else
{
info("No records found");
}
}
Can any one suggest me how to write a code which retrieves data using offset and limit that is taken from a webservice request.
limit and offset are not available in x++ when querying AX.
In my opinion you have 2 options to acheive the same goal.
Order your result set by recId, store the recId, and the use where recId > yourRecId for your offset. You would also need to count the records manually using something like while select.
Use x++ to query the SQL database directly, in which case you should be able to use any SQL supported by the server
You will most likely do not need to make a service yourself, as there are standard ways to do it.
Take a look on the answers here: Fetching data from dynamics ax 2009 using Ax webservices and C#
Also take a look on this screencast.

Using Linq, I get this: There is already an open DataReader associated with this Command which must be closed first

Here's what I'm trying to do:
IEnumerable<OfficeView> allOffices = GetAllOffices(); //this method also uses some linq query
foreach (var office in allOffices)
{
officeSales.Add(
new Tuple<int, decimal>(office.Id, GetSaleAmount(office.Id, someParams)));
}
public decimal GetAgentSaleAmount(int officeRef, someTypes someParams)
{
var q = ObjectQuery.Where
(i => i.officeId == officeRef && i.someOtherStuff == someParams)
.ToList();
return q.Sum(i => i.NetPrice);
}
I can't set MultipleActiveResultSets = true. Instead, as suggested here, I tried to do .ToList() before doing the summation, but got the same error. (and even if I wouldn't get the error, I think it would cause heavy load to fetch everything just to get the summation of one field)
I will be super thankful for any suggestion to solve this problem!
Update: The problem was all about GetAllOffices(), which returned IEnumerable (which leaves the DataReader open). I changed the first line as below and it worked. Thanks a lot guys :)
IEnumerable<OfficeView> allOffices = GetAllOffices().ToList();
Error said that reader is already opened, that means that you have run some query before which needs to close.
Write .ToList() to that linq query and do same for other queries too.
I think you are trying to do both adding and querying at the same time.You need to finish adding "Sale" object to "Sales" collection before trying to calculate the sales value.
In other words, you cannot query until the transaction is committed. Hope that helps.

EF4 throws NotSupported exception when it (imho) shouldn't

OK, this thing just puzzles me.
I have a table, say Users, with columns UserID, Name, etc. Have an object mapped to it using CTP5. So now I want to test it, and do the following:
List<User> users = new List();
// Some init code here, making say 3 users.
using (UsersDbContext)
{
// insert users
}
So far so good, works fine.
Now I want to see if the records match, so I select the users back using the following code.
using (UsersDbContext dbc = UsersDbContext.GetDbContext())
{
List<Users> usersRead = dbc.Users.Where(x => x.ID >= users[0].ID && x.ID <= users[users.Count - 1].ID).ToList();
}
This throws and exception:
System.NotSupportedException: LINQ to
Entities does not recognize the method
'User get_Item(Int32)' method, and
this method cannot be translated into
a store expression.
EF has difficulties seeing that I'm just asking to return an int in Users[0].ID ?
If I replace a call to users[0].ID with a straight int - works fine.
I get what it's trying to do, but I thought it should be pretty easy to check if the method belongs to .NET or Sql Server ?
You are trying to access an indexer in an EF expression, which doesn't translate to an SQL query. You'll have to move the parameters outside the query like this:
int first = users[0].ID;
int last = users[users.Count - 1].ID;
List<Users> usersRead = dbc.Users.Where(x => x.ID >= first && x.ID <= last).ToList();

Best practices re: LINQ To SQL for data access

Part of the web application I'm working on is an area displaying messages from management to 1...n users. I have a DataAccess project that contains the LINQ to SQL classes, and a website project that is the UI. My database looks like this:
User -> MessageDetail <- Message <- MessageCategory
MessageDetail is a join table that also contains an IsRead flag.
The list of messages is grouped by category. I have two nested ListView controls on the page -- One outputs the group name, while a second one nested inside that is bound to MessageDetails and outputs the messages themselves. In the code-behind for the page listing the messages I have the following code:
protected void MessageListDataSource_Selecting(object sender, LinqDataSourceSelectEventArgs e)
{
var db = new DataContext();
// parse the input strings from the web form
int categoryIDFilter;
DateTime dateFilter;
string catFilterString = MessagesCategoryFilter.SelectedValue;
string dateFilterString = MessagesDateFilter.SelectedValue;
// TryParse will return default values if parsing is unsuccessful (i.e. if "all" is selected"):
// DateTime.MinValue for dates, 0 for int
DateTime.TryParse(dateFilterString, out dateFilter);
Int32.TryParse(catFilterString, out categoryIDFilter);
bool showRead = MessagesReadFilter.Checked;
var messages =
from detail in db.MessageDetails
where detail.UserID == (int)Session["UserID"]
where detail.Message.IsPublished
where detail.Message.MessageCategoryID == categoryIDFilter || (categoryIDFilter == 0)
where dateFilter == detail.Message.PublishDate.Value.Date || (dateFilter == DateTime.MinValue)
// is unread, showRead filter is on, or message was marked read today
where detail.IsRead == false || showRead || detail.ReadDate.Value.Date == DateTime.Today
orderby detail.Message.PublishDate descending
group detail by detail.Message.MessageCategory into categories
orderby categories.Key.Name
select new
{
MessageCategory = categories.Key,
MessageDetails = categories.Select(d => d)
};
e.Result = messages;
}
This code works, but sticking a huge LINQ statement like this in the code-behind for a LinqDataSource control just doesn't sit right with me.
It seems like I'm still coding queries into the user interface, only now it's LINQ instead of SQL. However, I feel that building another layer between the L2S classes and the UI would cut back on some of the flexibility of LINQ. Isn't the whole point to reduce the amount of code you write to fetch data?
Is there some possible middle ground I'm not seeing, or am I just misunderstanding the way LINQ to SQL is supposed to be used? Advice would be greatly appreciated.
All your LINQ querys should be in a business logic class, no change from older methodologies like ADO.
If you are a purist you should always return List(of T) from your methods in the business class, in fact, the datacontext should only be visible to the business classes.
Then you can manipulate the list in the user interface.
If you are a pragmatist, you can return a IQueryable object and make some manipulations in the user interface.
Regardless of LINQ, I think that mixing presentation code with database-relaed code is not a good idea. I would create a simple DB abstraction layer on top of LINQ queries. In my opinion LINQ is just a convenient tool, that doesn't have a serious impact on traditional application design.

Resources