I am utilizing Devexpress Gridview and I am having a caching problem.
I have developed a page like here: http://mvc.devexpress.com/GridView/SimpleCustomBinding
It is working as it is supposed to be. However, if I update a column value in the database (Mssql), Gridview does not change the value.
Searched the web and found EnableRowsCache must be false but I could not implemented it since I think this property is available for different kind (or version) of Gridview and We have been using MVC extensions.
Does anybody know how to disable cache and make it show the "fresh" data?
------ UPDATE ------
After a lot of digging and searching, it is clear now that the caching is not due to devexpress, but it is the result of linq to sql. It is a property of linq that it caches the results of view and does not show the updated value.
This issue was a major headheache to us and now I have come up with a conclusion with my colleague.
PROBLEM
First of all, suppose that you have a view in your db, name: ViewBook
ViewBook
Id | Title | Author
And you write the following query:
(from VB in Connection.ViewBook
select VB).ToList();
As a result you will get a list of rows.
Then, if you update a row in your db, this query will not show the fresh data, still returns the old data.
SOLUTION
In order to solve this, first define an object:
public class ViewBookObject : ViewBook
{
//this object will have all the properties of ViewBook.
}
then in the query:
(from VB in Connection.ViewBook
select new ViewBookObject {
Id = VB.Id,
Title = VB.Title,
Author = VB.Author
}).ToList();
This query will always show the fresh data.
CONCLUSION
I have written this solution to here for people who have similar problem to this situation.
I hope this helps everyone.
Related
Hi :) What I'm trying to achieve is creating a Contact selector that, when you click on the selector icon, it brings up a filtered result of the contacts table that only shows Contacts related to that specific company, as shown below:
The above image is in the Sales Orders screen, and I'm aiming to actually have it in the Projects screen. So when I tried moving it over, making sure to have the same setup, it doesn't seem to be working in the Projects screen.
When I try opening the selector, the box is empty. I thought that maybe the problem was that the values I was trying to match between the PMProject table and the BAccount table weren't matching, so I used the Description field to output the values I was getting, and they appear to be the same.
This is the setup I am using to create the selector:
[PXUIField(DisplayName="Contact")]
[PXSelector(typeof(Search2<Contact.displayName,
LeftJoin<BAccount, On<BAccount.bAccountID, Equal<Contact.bAccountID>>>,
Where<Contact.contactType, Equal<ContactTypesAttribute.person>>>))]
[PXRestrictor(typeof(
Where<Current<PMContact.customerID>,
Like<BAccount.bAccountID>>), "")]
It's exactly the same setup that I was using for the Sales Order screen, just obviously now it's using the CustomerID of PMProject instead.
Is there something I am doing incorrectly? Any help would be appreciated :D
UPDATE
Thanks for the answer Joseph! The contact field still shows up as being empty when I click into it. See below:
This is how I added the solution:
It seems that your join with the BAccount might not be required.
Also, where are you using the displayname in "Search2<Contact.displayName"?
Did you try something like this:
[PXSelector(typeof(Search<Contact.contactID, Where<Contact.contactType, Equal<ContactTypesAttribute.person>,
And<Where<Contact.contactID, Equal<Current<PMContact.customerID>>>>>>))]
I managed to solve this issue. Joseph's answer made me rethink how I was matching contacts with the current project, as instead of using the BAccount table, I could use the Contact table instead.
I found that I just needed to compare the Contact.bAccountID field with the value of the PMContact.customerID field, and that would give me all the associated contacts.
Adding this comparison to the PXRestrictor solved this issue for me :)
[PXDBString(50)]
[PXUIField(DisplayName="Contact")]
[PXSelector(typeof(Search2<Contact.displayName,
LeftJoin<BAccount, On<BAccount.bAccountID, Equal<Contact.bAccountID>>>,
Where<Contact.contactType, Equal<ContactTypesAttribute.person>>>))]
[PXRestrictor(typeof(
Where<Current<PMContact.customerID>,
Like<Contact.bAccountID>>), "")]
So, I have this lambda expression and it works just fine
list = list.Where(x => x.ListaDocumentoCaixa.Any(d => d.Observacao.Contains(term.Trim())));
I must add that this column is a varchar(6000) field. So far, this has been working just fine as I mentioned, but just recently I've ran into an issue. It seems that if the term of the search occurs from position 4001 of the string and on, the query fails to return anything to me.
After some debbuging I've found this commented on the query produced by Entity Framework
-- p__linq__0: 'maria stela gonsa' (Type = String, Size = 4000)
Then after some research I found this to be Entity's common behaviour, however, I can't have this kind of limitation on the application. My question is: Is there any way to change this behaviour ? I would like very much to avoid having to write this query as plain text and run this with ExecuteQuery if possible.
Thanks in advance for the help!
I would recommend you follow the following article, assuming you are using SQL server, about how to create a full text search index, and use it in Entity Framework with C#.
Running LIKE statements (which is what Contains() maps to) is HIGHLY inefficient on large varchar fields.
https://www.mikesdotnetting.com/article/298/implementing-sql-server-full-text-search-in-an-asp-net-mvc-web-application-with-entity-framework
EDIT: The summary of the link is:
1.) Create a full text index on the field using SQL server's wizard. That full text field will allow CONTAINS and FREETEXT searches on the whole field, and be much more efficient.
2.) Write a stored procedure that joins the table in question to results from the free text index.
3.) Make an Entity Framework class to represent results from that stored procedure, and use EF to call in and return a list of those results.
I'm looking at updating stored values in a RethinkDB using the C# RethinkDB.Driver library and I'm just not getting it right.
I can achieve an update by getting the result, altering that object then making a separate call to update with that object. When there are many calls to a record to update like this, the value being updated elsewhere whilst the application is working with the record.
TestingObject record = r.Db("test").Table("learning").Get("c8c54346-e35f-4025-8641-7117f12ebc5b").Run(_conn);
record.fieldNameIntValue = record.fieldNameIntValue + 1;
var result = r.Db("test").Table("learning").Get("c8c54346-e35f-4025-8641-7117f12ebc5b").Update(record).Run(_conn);
I've been trying something along these lines :
var result = r.Db("test").Table("learning").Get("c8c54346-e35f-4025-8641-7117f12ebc5b").Update(row => row["fieldNameIntValue"].Add(1)).Run(_conn);
but the result errors with Inserted value must be an OBJECT (got NUMBER):101 which suggests this is only passing the field value back instead of updating the object.
Ideally I'd like to update multiple columns at once, any advice is appreciated :)
This is an example that works in the ReQL data explorer. You can chain as may filters before the update as you want. I assume this will translate to the C# Driver, but I dont have any experience with that.
r.db('database').table('tablename').update({clicks: r.row("clicks").add(1)}).run().then(function(result){ ...
Thanks T Resudek your answer and a clearer head helped emphasised the need to map the calculation to the property.
Looking at the javadocs for update it has HashMap method which I followed with the c# library and it works.
var result = r.Db("test").Table("learning").Get("c8c54346-e35f-4025-8641-7117f12ebc5b").Update(row => r.HashMap("fieldNameIntValue",row["fieldNameIntValue"].Add(1))).Run(_conn);
I'd be interested to know if this is the right way or was a better way.
I'm new to n-tier enterprise development. I just got quite a tutorial just reading threw the 'questions that may already have your answer' but didn't find what I was looking for. I'm doing a geneology site that starts off with the first guy that came over on the boat, you click on his name and the grid gets populated with all his children, then click on one of his kids that has kids and the grid gets populated with his kids and so forth. Each record has an ID and a ParentID. When you choose any given person, the ID is stored and then used in a search for all records that match the ParentID which returns all the kids. The data is never changed (at least by the user) so I want to just do one database access, fill all fields into one datatable and then do a requery of it each time to get the records to display. In the DAL I put all the records into a List which, in the ObjectDataSource the function that fills the GridView just returns the List of all entries. What I want to do is requery the datatable, fill the list back up with the new query and display in the GridView. My code is in 3 files here
(I can't get the backticks to show my code in this window) All I need is to figure out how to make a new query on the existing DataTable and copy it to a new DataTable. Hope this explains it well enough.
[edit: It would be easier to just do a new query from the database each time and it would be less resource intensive (in the future if the database gets too large) to store in memory, but I just want to know if I can do it this way - that is, working from 1 copy of the entire table] Any ideas...
Your data represents a tree structure by nature.
A grid to display it may not be my first choice...
Querying all data in one query can be done by using a complex SP.
But you are already considering performance. Thats always a good thing to keep in mind when coming up with a design. But creating something, improve it and only then start to optimize seems a better to go.
Since relational databases are not real good on hierarchical data, consider a nosql (graph)database. As you mentioned there are almost no writes to the DB, nosql shines here.
I have 3 tables:
Order,
OrderStates,
OrderStateDefinition
An Order has many OrderStates which then has one OrderStateDefinition.
I have a gridview in which I am trying to display only one value inside the OrderStates collection - the latest OrderState that has been added.
I've read a little about subqueries but I'm unsure about how to go about achieving the result I want.
Sorry bout the lack of information, I had a nice picture all set up of the table structure but stackoverflow wouldn't let me upload it.
Edit -
OK I figured out how to do this. As the GridView was being populated I used the event OnRowCreated to then set the text of the field I required. To get to the control I needed I used the e.Row.FindControl.
The code for it was pretty simple in the end. I always seem to figure this stuff out when I finally ask for help.
try
{
int orderID = e.Row.RowIndex;
Order order = ShopEntities.Orders.Single(o => o.OrderStateID == orderID);
// I can now get the list of orderstates
OrderStateDefinition osd = order.OrderStates.OrderBy(o => o.Date).Last().OrderStateDefinition;
((Label)e.Row.FindControl("Label2")).Text = osd.State;
}
catch
{
}
I often find it's easier to create your own SQL that does this. the sql might be a little complex, but it's easier than mucking with the c#.