We have a MVC 4 Web application. I used miniprofiler to check how long it is taking and it shows that the render of a view with three partial views is taking a very long time. I tried moving the information in the partial views directly onto the page and that didn't make a difference in the times at all. What should I do to reduce the render time? Any tips on where I should start looking? As you can see, the render is taking 48 seconds.
**| duration | from start(ms)**
|http://localhost:61380/CaseContacts | 653.7 | +0.0
|Controller: CaseController.Contacts | 11.9 | +641.1
| Contacts view - not an ajax request | 0.3 | +651.7
| populating view model | 0.0 | +652.1
| getting list of contacts | 374.4 | +652.1
| Find: Contacts | 499.8 | +1033.6
| Render: Contacts | 48400.8 | +1535.2
**| client event |duration(ms)| from start(ms)**
|Request start | | +2.0
|Response | 1.0 | +52245.0
|Dom loading | | +52247.0
|scripts | 390.0 | +52315.0
|Dom Content Loaded Event| 29.0 | +52707.0
|Dom Interactive | | + 52707.0
|Load Event | | + 52760.0
|Dom Complete | | + 52760.0
Update:
public IQueryable<T> FindQueryable(Expression<Func<T, bool>> predicate, Func<T, Object> orderBy)
{
return this.db.GetAll<T>().Where(predicate).OrderBy(orderBy).AsQueryable<T>();
}
public class ContactRepository : Repository<USRContact>, IContactRepository<USRContact>
{
public IList<ContactNameViewModel> GetAll(int fieldOfficeID, string searchText = "")
{
if (searchText.Length > 0)
return Mapper.Map<IList<USRContact>, IList<ContactNameViewModel>>(this.FindQueryable(x => (x.FieldOfficeID == fieldOfficeID) &&
(x.FormalName.Contains(searchText) || x.PreferredName.Contains(searchText) || x.Alias.Contains(searchText) || x.Pseudonym.Contains(searchText)), x => (x.STMGender.Gender)).ToList());
else
return Mapper.Map<IList<USRContact>, IList<ContactNameViewModel>>(this.FindQueryable(x => (x.FieldOfficeID == fieldOfficeID)).ToList());
}
Then my controller is loading the results onto a viewmodel and then:
#Html.Partial("~/Views/Shared/Contacts/ContactNameList.cshtml", Model.Contacts)
The partial view contains the following code:
#model IList<Casenator.Web.Models.Contact.ContactNameViewModel>
<ul id="NameList" style="margin-left:0">
#foreach (var item in Model)
{
#*<li>#Html.RouteLink(#item.FullName, "Contacts", new { id = item.ContactID })</li>*#
<li>#Ajax.RouteLink(item.FullName, "Contacts", new { id = item.ContactID }, new AjaxOptions { UpdateTargetId = "BasicInfo", OnSuccess="InitializeComboBoxes", OnBegin="LoadContact(" + item.ContactID + ")" }) </li>
}
</ul>
Any help will be appreciated!
Thanks,
Safris
What you are returning from query is important. If you are returning IEnumerable It would be better to reurn IQueryable. You may see this question it may help you in your situation
I don't think automapper like tools are designed to map many recoreds. you may try to map the object manually
Related
I have two sheets below. Links also added to each sheet for reference
Posts sheet:
id | title | tags
1 | title 1 | article, sports, football, england
2 | title 2 | news, sports, spain, france
3 | title 3 | opinion, political, france
4 | title 4 | news, political, russia
5 | title 5 | article, market, Germany
Tags sheet:
location | type | category
england | article | sports
spain | news | political
germany | opinion | market
russia | | football
france |
About each sheets:
Posts sheet consists of list of posts with title and tags associated with it.
Tags sheet consists of list of tags categorized to understandable heads.
What I am trying to do:
I need to extract the value from the tags column in Posts sheet and add the tag to individual columns based on what head its coming in tags sheet.
Desired Output:
id | title | type | category | location
1 | title 1 | article | sports, football | england
2 | title 2 | news | sports | spain, france
3 | title 3 | opinion | political | france
4 | title 4 | news | political | russia
5 | title 5 | article | market | Germany
I made this sample code for Google Apps Script that can help you sort the information. I added some comments in case you want to modify some of the columns or cells working on it. Here is the code:
function Split_by_tags() {
// Get the sheets you will work with by the name of the tab
const ss_posts = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Posts Sheet");
const ss_tags = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Tags Sheet");
const ss_output = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Expected Output");
// Get the range of the columns to of "Posts Sheet" we will work with
// If range_1 is the ID, range 2 is the title, range 3 is tags
// If you change the columns in the future, you only need to update this part
let range_1 = ss_posts.getRange("A2:A").getValues().flat();
let range_2 = ss_posts.getRange("B2:B").getValues().flat();
let range_3 = ss_posts.getRange("C2:C").getValues().flat();
// filter the arrays information to only the cells with values for "Posts Sheet"
// This way, you can add new information to the tags rows and they will be added
range_1 = range_1.filter((element) => {return (element !== '')});
range_2 = range_2.filter((element) => {return (element !== '')});
range_3 = range_3.filter((element) => {return (element !== '')});
// The values we will compare the tags with in arrays
let range_type = ss_tags.getRange("A2:A").getValues().flat();
let range_location = ss_tags.getRange("B2:B").getValues().flat();
let range_category = ss_tags.getRange("C2:C").getValues().flat();
// filter the arrays information to only the cells with values for "Tags Sheet"
// This way, you can add new information to the tags rows and they will be added
range_type = range_type.filter((element) => {return (element !== '')});
range_location = range_location.filter((element) => {return (element !== '')});
range_category = range_category.filter((element) => {return (element !== '')});
// new Arrays where the information will be sort, I added a new tag option called "Other"
// just in case the information in the column 2 has a value which is not under "Tags Sheet"
let type_tag = [];
let location_tag = [];
let category_tag = [];
let other_tag = [];
// for to copy the ID from "Posts Sheet" to "Expected Output"
for (let i=0; i< range_1.length ; i++){
ss_output.getRange(i+2,1).setValue(range_1[i]);
};
// for to copy the title from "Posts Sheet" to "Expected Output"
for (let j=0; j< range_2.length ; j++){
ss_output.getRange(j+2,2).setValue(range_2[j]);
};
// fuction to sort the tags from "Posts Sheet" base in "Tags Sheet"
function Separate_value(value_array){
for (let k=0; k < value_array.length; k++){
if(range_type.includes(value_array[k])){
type_tag.push(value_array[k]);
}
else if(range_location.includes(value_array[k])){
location_tag.push(value_array[k]);
}
else if(range_category.includes(value_array[k])){
category_tag.push(value_array[k]);
}
else{
other_tag.push(value_array[k]);
}
};
}
// Function to empty the arrays for the next loop
function Empty_value(){
type_tag = [];
location_tag = [];
category_tag = [];
other_tag = [];
}
// for to add the values we sorted to "Expected Output"
for (let e=0; e < range_3.length; e++ ){
let value_array = range_3[e].split(', ');
Separate_value(value_array)
ss_output.getRange(e+2,3).setValue(type_tag.join(", "));
ss_output.getRange(e+2,4).setValue(category_tag.join(", "));
ss_output.getRange(e+2,5).setValue(location_tag.join(", "));
ss_output.getRange(e+2,6).setValue(other_tag.join(", "));
Empty_value();
};
}
You can bound the script by accessing Extensions > Apps Script in your Google Sheet.
Copy and paste the sample code, and run it. The first time you run the Apps Script, it will ask you for permissions, accept those, and the information will get sorted.
You can also add a trigger to the Apps Script so it can sort the information automatically when new data is added.
Reference:
Create a bound Apps Script.
Create trigger.
I'm having a hard time trying to execute an update on multiple rows in a table.
I've tried this code:
PayoutEntities payoutdb = new PayoutEntities();
public void SaveStatusBatch(string batchid)
{
payout_transaction data = payoutdb.payout_transaction.Where(x => x.batchid == batchid).FirstOrDefault();
data.status = "Success";
payoutdb.SaveChanges();
}
But it only updates only a single row where the batchid is a match to what is indicated in the parameter. I'm using Èntity Framework in this.
This is how my table looks like:
|batchid|name|status|
|1 |John| |
|1 |Nick| |
|1 |Bill| |
|2 |Ara | |
I wanted to update the status of John,Nick and Bill to Success.
Do you have any suggestions on how am i supposed to do this?
The concept is to change all the data and then call the SaveChanges of the DBContext object. e.g.:
public void SaveStatusBatch(string batchid)
{
payout_transaction data = payoutdb.payout_transaction
.Where(x => x.batchid == batchid)
.ToList();
data.ForEach(a=> a.status = "Success");
payoutdb.SaveChanges();
}
I have a table like this:
+----+-------+------------------+
| ID | Name | TipoContenedorID |
+----+-------+------------------+
| 1 | first | 10 |
| 2 | two | 9 |
| 3 | three | 10 |
+----+-------+------------------+
So depending of "TipoContenedorID" I get the name of another table with anonymous type like this:
var vehiculo = _pService.Listar(x => x.TipoContenedor.CatalogosID.Equals("TCO"), includeProperties: "TipoContenedor").Select(x => new
{
x.TipoContenedor.ID,
x.TipoContenedor.Nombre
});
Problem is I just want to receive value one time. Actually I get:
TipoContenedor.Nombre = firstname
TipoContenedor.Nombre= secondname
TipoContenedor.Nombre = firstname
So I'm getting the first name twice. How do I distinct that TipoContenedorID if repeated just pass it? Regards
Add .Distinct()
var vehiculo = _pService
.Listar(x => x.TipoContenedor.CatalogosID.Equals("TCO"), includeProperties: "TipoContenedor")
.Select(x => new
{
x.TipoContenedor.ID,
x.TipoContenedor.Nombre
})
.Distinct();
verbDatabase Table
The data I'm using is the below and also in the screenshot above:
+----+------------+------------+------------+
| id | infinitive | ind pre je | ind pre tu |
+----+------------+------------+------------+
| 1 | aimer | aime | aimes |
| 2 | aller | vais | vas |
| 3 | courir | cours | cours |
| 4 | servir | sers | sers |
| 5 | mourir | meurs | meurs |
| 6 | dormir | dors | dors |
| 7 | sentir | sens | sens |
| 8 | vêtir | vêts | vêts |
| 9 | fuir | fuis | fuis |
| 10 | tenir | tiens | tiens |
+----+------------+------------+------------+
I'm new to coding and am working on a French conjugation app that tests users on their conjugation by displaying a verb in infinitive form (to verbLabel.text) and the tense required (to tenseLabel.text). The goal is for the user to input (to userInput.text)the conjugated form of that verb and press a button (checkAnswer) to check their answer. If the answer is correct, a new verb will be generated, etc.
I have a CoreData entity named verbDatabase with attributes named id, infinitive, indPreJe and indPreTu.
I've managed to generate a random row (to display a random verb) but I'm having trouble generating a random attribute (either indPreJe or indPreTu). To generate a random attribute and because attribute names must begin with a lowercase letter, I cannot use the same method as I did to generate a random row.
To solve this problem, I tried creating an array which holds attribute names and then generate a random number that then appends the attribute name to the fetch request that is displayed in tenseLabel.text but tenseLabel.text displays the string "verbDatabase[0].indPreJe" instead of the value of verbDatabase[0].indPreJe.
Is there any way to get the text label to display the value after it has been appended with the random attribute name instead of the string points to that value?
If I'm tackling my data in an inefficient way, is there a better way of storing my data into Core Data that will allow me to better access it with what I'm trying to do? I'm still trying to wrap my head around the Core Data structure. I've also considered saving the verbs as separate dictionaries with the tenses as their keys and conjugated forms as their corresponding values.
Ideally I would like to be able to allow users to select which tenses they would like to be tested on and also categorising the verbs - regular form, irregular form, common verbs, etc.
Thanks in advance for any help!
#IBOutlet weak var verbLabel: UILabel!
#IBOutlet weak var tenseLabel: UILabel!
#IBOutlet weak var userInput: UITextField!
#IBOutlet weak var textView: UITextView!
var currentRow: Int = 0
var countTenseColumns: Int = 2
var currentColumn: Int = 0
var columnNames = ["id","infinitive","indPreJe","indPreTu"]
#IBAction func checkAnswer(_ sender: Any) {
if userInput.text == verbDatabase[currentRow].indPreTu {
textView.text = "correct!"
viewWillLayoutSubviews()
userInput.text = nil
}
else {
textView.text = "the correct answer is \(verbDatabase[currentRow].indPreTu ?? "error")"
}
}
func randomNumberGeneratorRow() -> Int {
//generates random number from 1 to verbDatabase.count
return Int(arc4random_uniform(UInt32(verbDatabase.count)+1))
}
func randomNumberGeneratorColumn() -> Int {
//generates random number from 2 to number of columns with tenses
return Int(arc4random_uniform(UInt32(countTenseColumns)+2))
}
override func viewWillLayoutSubviews() {
currentRow = self.randomNumberGeneratorRow()
currentColumn = self.randomNumberGeneratorColumn()
var columnName = "verbDatabase[0].\(columnNames[currentColumn])"
verbLabel.text = verbDatabase[currentRow].infinitive
tenseLabel.text = columnName
}
Is there any way to get the text label to display the value after it has been appended with the random attribute name instead of the string points to that value?
Yes, you can use value(forKey:) (see the documentation here):
var columnName = columnNames[currentColumn]
tenseLabel.text = verbDatabase[currentRow].value(forKey:columnName)
I am developing a GRAILS application (I'm new to GRAILS and inherited the project from a previous developer). I'm slowly getting a small grasp for how GRAILS operates and the use of DOMAIN classes, hibernate etc. The MySQL db is hosted on Amazon and we're using ElasticCache.
Do any of you more knowledgeable folks know how I can go about converting the following SQL statement into domain classes and query criteria.
if(params?.searchterm) {
def searchTerms = params.searchterm.trim().split( ',' )
def resultLimit = params.resultlimit?: 1000
def addDomain = ''
if (params?.domainname){
addDomain = " and url like '%${params.domainname}%' "
}
def theSearchTermsSQL = ""
/*
* create c.name rlike condition for each search term
*
*/
searchTerms.each{
aSearchTerm ->
if( theSearchTermsSQL != '' ){
theSearchTermsSQL += ' or '
}
theSearchTermsSQL += "cname rlike '[[:<:]]" + aSearchTerm.trim() + "[[:>:]]'"
}
/*
* build query
*
*/
def getUrlsQuery = "select
u.url as url,
c.name as cname,
t.weight as tweight
from
(category c, target t, url_meta_data u )
where
(" + theSearchTermsSQL + ")
and
t.category_id = c.id
and t.url_meta_data_id = u.id
and u.ugc_flag != 1 " + addDomain + "
order by tweight desc
limit " + resultLimit.toLong()
/*
* run query
*
*/
Sql sqlInstance = new Sql( dataSource )
def resultsList = sqlInstance.rows( getUrlsQuery )
}
The tables are as follows (dummy data):
[Category]
id | name
-----------
1 | small car
2 | bike
3 | truck
4 | train
5 | plane
6 | large car
7 | caravan
[Target]
id | cid | weight | url_meta_data_id
----------------------------------------
1 | 1 | 56 | 1
2 | 1 | 76 | 2
3 | 3 | 34 | 3
4 | 2 | 98 | 4
5 | 1 | 11 | 5
6 | 3 | 31 | 7
7 | 5 | 12 | 8
8 | 4 | 82 | 6
[url_meta_data]
id | url | ugc_flag
---------------------------------------------
1 | http://www.example.com/foo/1 | 0
2 | http://www.example.com/foo/2 | 0
3 | http://www.example.com/foo/3 | 1
4 | http://www.example.com/foo/4 | 0
5 | http://www.example.com/foo/5 | 1
6 | http://www.example.com/foo/6 | 1
7 | http://www.example.com/foo/7 | 1
8 | http://www.example.com/foo/8 | 0
domain classes
class Category {
static hasMany = [targets: Target]
static mapping = {
cache true
cache usage: 'read-only'
targetConditions cache : true
}
String name
String source
}
class Target {
static belongsTo = [urlMetaData: UrlMetaData, category: Category]
static mapping = {
cache true
cache usage: 'read-only'
}
int weight
}
class UrlMetaData {
String url
String ugcFlag
static hasMany = [targets: Target ]
static mapping = {
cache true
cache usage: 'read-only'
}
static transients = ['domainName']
String getDomainName() {
return HostnameHelper.getBaseDomain(url)
}
}
Basically, a url from url_meta_data can be associated to many categories. So in essence what I'm trying to achieve should be a relatively basic operation...to return all the urls for the search-term 'car', their weight(i.e importance) and where the ugc_flag is not 1(i.e the url is not user-generated content). There are 100K + of records in the db and these are imported from a third-party provider. Note that all the URLs do belong to my client - not doing anything dodgy here.
Note the rlike I've used in the query - I was originally using ilike %searchterm% but that would find categories where searchterm is part of a larger word, for example 'caravan') - unfortunately though the rlike is not going to return anything if the user requests 'cars'.
I edited the code - as Igor pointed out the strange inclusion originally of 'domainName'. This is an optional parameter passed that allows the user to filter for urls of only a certain domain (e.g. 'example.com')
I'd create an empty list of given domain objects,
loop over the resultsList, construct a domain object from each row and add it to a list of those objects. Then return that list from controller to view. Is that what you're looking for?
1) If it's a Grails application developed from a scratch (rather than based on a legacy database structure) then you probably should already have domain classes Category, Target, UrlMetaData (otherwise you'll have to create them manually or with db-reverse-engineer plugin)
2) I assume Target has a field Category category and Category has a field UrlMetaData urlMetaData
3) The way to go is probably http://grails.org/doc/2.1.0/ref/Domain%20Classes/createCriteria.html and I'll try to outline the basics for your particular case
4) Not sure what theDomain means - might be a code smell, as well as accepting rlike arguments from the client side
5) The following code hasn't been tested at all - in particular I'm not sure how disjunction inside of a nested criteria works or not. But this might be suitable a starting point; logging sql queries should help with making it work ( How to log SQL statements in Grails )
def c = Target.createCriteria() //create criteria on Target
def resultsList = c.list(max: resultLimit.toLong()) { //list all matched entities up to resultLimit results
category { //nested criteria for category
//the following 'if' statement and its body is plain Groovy code rather than part of DSL that translates to Hibernate Criteria
if (searchTerms) { //do the following only if searchTerms list is not empty
or { // one of several conditions
for (st in searchTerms) { // not a part of DSL - plain Groovy loop
rlike('name', st.trim())) //add a disjunction element
}
}
}
urlMetaData { //nested criteria for metadata
ne('ugcFlag', 1) //ugcFlag not equal 1
}
}
order('weight', 'desc') //order by weight
}
Possibly the or restriction works better when written explicitly
if (searchTerms) {
def r = Restrictions.disjunction()
for (st in searchTerms) {
r.add(new LikeExpression('name', st.trim()))
}
instance.add(r) //'instance' is an injected property
}
Cheers,
Igor Sinev