I had a test case that looks like this:
[TestMethod]
public void Things_can_be_saved()
{
var ts = DateTime.Now;
var thing = new Thing()
{
Name = "Some name",
TimeStamp = ts
};
// save it
var context = new MyDataContext(testDb);
context.Things.Add(thing);
context.SaveChanges();
// pull from a fresh context so we know it's a db pull not cached
var context2 = new MyDataContext(testDb);
var fetched = context2.Things.FirstOrDefault(t => t.TimeStamp == ts);
Assert.AreEqual(thing.Name, fetched.Name);
}
So, when I run this, I can look in the DB and see 'thing' present in the db. I can see that the stored Timestamp column for it is equal to the value in the ts variable at runtime. But 'fetched' is null, indicating that EF can't find it in the FirstOrDefault query. Is there something I'm missing about DateTime equality?
You probably need to change your column in the database to be datetime2 instead of datetime
Also see this thread: DateTime2 vs DateTime in SQL Server
Related
I am trying to get readable date from Timestamp data type in my firestore database.
for (var ticketDoc of ticketsSnapshot.docs) {
var timeStamp = await ticketDoc.data().TimePreferred;
console.log(timeStamp.toDate());
var time = new Date(timeStamp).toDate();
ticketDoc.data().TimePreferred = time;
tickets.push(ticketDoc.data());
}
I read the question about a similar problem at :
How do I convert a Firestore date/Timestamp to a JS Date()?
so, i tried to do same and i expect the output of readable date, although it gives me the correct result in
console.log(timeStamp.toDate());
but also it gives me an error. Console output as follow :-
2019-04-10T06:30:00.000Z
TypeError: (intermediate value).toDate is not a function
Not : I am trying to get readable date in postman
I don't know why this timestamp object doesn't have the .toDate() extension, but if it has the 'seconds' and 'nanoseconds' properties, you can turn it to a JS Data with
Date(data.seconds)
Change the following line:
var time = new Date(timeStamp).toDate();
into this:
var time = new Date(timeStamp).toDateString();
From the docs:
A string representing the date portion of the given Date object in human readable form in American English.
You can try in the following way
{{ formatDate(new Date(data.seconds*1000)) }}
You can use the format date function to display in desired format.
import moment from "moment";
format_date(value) {
if (value) {
return moment(String(value)).format("DD/MM/YYYY");
}
},
Have you tried changing this to
var time = (new Date(timeStamp)).toDateString();
If the TimePreferred field in your document is a Timestamp, you can get a valid Date object from it by simply calling toDate() on it.
So:
for (var ticketDoc of ticketsSnapshot.docs) {
var date = ticketDoc.data().TimePreferred.toDate();
}
None of these calls are asynchronous or returning a promise, so you don't need await.
From reasons that I don't know, it doesn't work at times, so a safer option would be to use the seconds and nanoseconds attributes found in the timestamp to convert it to date as follows:
const date = new Date(timestamp.seconds*1000 + timestamp.nanoseconds/100000)
// construct the date from the absolute time in milliseconds
Note:
1 second = 1000 ms
1 nanosecond = 10^-6 ms
You have to first make sure that the timestamp object is truly of type Timestamp.
to do this, after you get the Timestamp from Firebase, create the Timestamp object:
const timestampObject: Timestamp = !!timeStamp
? new Timestamp(timeStamp.seconds, timeStamp.nanoseconds)
: null;
For Angular
import { Location, DatePipe } from '#angular/common';
constructor(
public datepipe: DatePipe
) { }
const dayAsTimestamp = your_Timestamp_value;
const dayAsDate = new Date(dayAsTimestamp.seconds * 1000);
const dayAsString = this.datepipe.transform(dayAsDate, 'dd-MMM-yyyy');
I'm using SQLite with sql.js on my project and I have been having some trouble with my implementation. Seems like the queries are being run on the database twice because for the for the INSERT statements I get 2 records in the DB.
The way I do it, I create the SQL and then pass it on to this method (the opts variable contains all of the data being put into the database):
prepareStatementAndCompileResults(db, sql, opts){
const stmt = db.prepare(sql);
const result = stmt.getAsObject(opts);
var rows = [];
if(!this.isEmpty(result)){ // isEmpty is a simple method that checks for empty objects
rows.push(result);
}
while(stmt.step()) {
var row = stmt.getAsObject();
rows.push(row);
}
this.saveToFile(db);
stmt.free();
return rows;
},
Here is a sample SQL INSERT that is being run twice
INSERT OR IGNORE INTO tag_event (tag_id, event_id, unique_string)
VALUES (:tag_id,:event_id, :unique);
Here is what the opts variable would look like for this query:
var opts = {
[':tag_id']: 1,
[':event_id']:1,
[':unique']: '1-1'
}
Because you're pushing it into row 2 time.
// if not empty will add to row
if(!this.isEmpty(result)){ // isEmpty is a simple method that checks for empty objects
rows.push(result);
}
// not sure what step() does but I'm assuming this will also run
while(stmt.step()) {
var row = stmt.getAsObject();
rows.push(row);
}
Verify by using a debugger or just console.log(rows) after the while loop before the save
So, what it turns out I needed to do was bind the variables to the prepared statement before getting the rather than binding them through getAsObject. This is much more efficient. My API response time on a local test went from 785ms to 14.5ms
prepareStatementAndCompileResults(db, sql, opts){
const rows = [];
const stmt = db.prepare(sql);
stmt.bind(opts);
while(stmt.step()) {
var row = stmt.getAsObject();
rows.push(row);
}
this.saveToFile(db);
stmt.free();
return rows;
},
I have a userevent script to change the Field in Contract record from PO record. The Script is running fine. But whenever I edit a contract record and try to submit it : It throws the error "Another user has updated this record since you began editing it. Please close the record and open it again to make your changes".
May I know the reason behind this ?
/*---------------------------------------------------------------------------------------------------------------
Description : Whenever the PO vendor is changed(due to Split vendor) that should replace the same in Contract page record automatically.
Script type : User Event Script
Script id : customscript452
Version : 1.0
Applied to : Contract
----------------------------------------------------------------------------------------------------------------*/
function srchfield()
{
var stRecordid = nlapiGetRecordId(); //returns the contract id
if(stRecordid== undefined || stRecordid== null || stRecordid==' ')
{
}
else
{
var stRecordtype = nlapiGetRecordType(); //returns the contract record type = jobs
var stRecord = nlapiLoadRecord(nlapiGetRecordType(), stRecordid);
nlapiLogExecution('debug','Load Object',stRecord);
var stContractID = stRecord.getFieldValue('entityid'); //returns the value of the field contractid whose fieldid is = entityid
nlapiLogExecution('debug','stContractID',stContractID);
var stCompanyName = stRecord.getFieldValue('companyname'); //returns the value of the field company name whose fieldid is = companyname
nlapiLogExecution('debug','stCompanyName',stCompanyName);
var stConcatenate = stContractID+" : "+stCompanyName; //Concatenate the two Fields to get the result which needs to be found in PO
var arrFilters = new Array(); // This is Array Filters all the Purchase Order Record Search
arrFilters.push(new nlobjSearchFilter('type', null, 'anyof',
[
'PurchOrd'
]));
arrFilters.push(new nlobjSearchFilter('mainline', null, 'is', 'T')); //This is to exclude line level results
arrFilters.push(new nlobjSearchFilter('custbodycontract', null, 'is', stRecordid)); //This is Filters in Contracts Search
var arrColumns = new Array();
arrColumns.push(new nlobjSearchColumn('entity')); //This is Search Column Field in Records
var arrSearchresults = nlapiSearchRecord('purchaseorder', null, arrFilters, arrColumns); //This is Filters in Search Result Purchase Order
if(arrSearchresults== undefined || arrSearchresults== null || arrSearchresults==' ')
{
}
else
{
var length = arrSearchresults.length;
}
if(length== undefined || length== null || length==' ')
{
}
else
{
for (var i = 0; arrSearchresults != null && i < arrSearchresults.length; i++)
{
var objResult = arrSearchresults[i];
var stRecId = objResult.getId();
var stRecType = objResult.getRecordType();
var stCntrctName = objResult.getValue('entity'); //This is Value are Get Purchase Order Records and Field for Vendor = entity
}
}
//var record = nlapiLoadRecord(nlapiGetRecordType(), stRecordid, stCntrctName);
if (stCntrctName =='custentityranking_vendor_name')
{
}
else
{
var stChangeName = stRecord.setFieldValue('custentityranking_vendor_name', stCntrctName); //This is Value are the Set in Main Vendor Field = custentityranking_vendor_name
nlapiSubmitRecord(stRecord, null, null); // Submit the Field Value in Record Type
}
}
}
The User Event script executes as the Contract record is being saved to the database. At the same time, you are loading a second copy of the record from the database and trying to submit the copy as well. This is causing the error you're seeing.
You fix this by just using nlapiSetFieldValue to set the appropriate field on the Contract.
I might also recommend getting more familiar with JavaScript by going through the JavaScript Guide over at MDN. In particular, take a look at the Boolean description so that you know how JavaScript evaluates Boolean expressions. This will help you greatly reduce the amount of code you've written here, as many of your conditionals are unnecessary.
What userevent do you have? It is happening depending on what type of user event and API you are using. Looking at your code, you are trying to load contract record that is already updated at the database. So you might consider below to address your issue. Hope, it helps.
If it is a before submit, you don't need to load the record where the script is deployed.
Just use nlapiGet* and nlapiSet* to get and set values. You also don't need to use nlapiSubmitRecord to reflect the change. With before submit, it executes before the record is being saved to the database. So your changes will still be reflected.
Then if it is after submit, it will be executed after the record has been saved to the database, Thus you might use the following API depending on your needs. Actually, this is the best practice to make sure the solution .
nlapiGetNewRecord - only use this if the script only needs to retrieve info from header and sublists. And nothing to set.
nlapiLookupField - use this if the script only needs to get value/s at the header and nothing from the line.
nlapiSubmitField - the script don't need to load and submit record if the changes only on header. Just use this API.
nlapiLoadRecord and nlapiSubmitRecord- use the former if the script will have changes at the line and then use the latter api to commit it on the database.
Being a user event script code, The code you showed is very not good considering performance.
Here is the sample you can merge
var stRecordid = nlapiGetRecordId(); //returns the contract id
// Every record has an internal id associated with it. No need to add condition explicitly to check if its null
var stRecordtype = nlapiGetRecordType();
var fields = ['entityid','companyname'];
var columns = nlapiLookupField(stRecordtype, stRecordid, fields);
var stContractID = columns.entityid;
var stCompanyName = columns.companyname;
nlapiLogExecution('debug','stContractID/stCompanyName',stContractID+'/'+stCompanyName);
var stConcatenate = stContractID+" : "+stCompanyName; //Concatenate the two Fields to get the result which needs to be found in PO
//
//your code of search
//you can improve that code also by using nlapilook up
nlapiSubmitField(stRecordtype, stRecordid, 'custentityranking_vendor_name', 'name to be updated');
In an odata webapi call which returns a PageResult I extract the requestUri from the method parameter, manipulate the filter terms and then construct a new ODataQueryOptions object using the new uri.
(The PageResult methodology is based on this post:
http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options )
Here is the raw inbound uri which includes %24inlinecount=allpages
http://localhost:59459/api/apiOrders/?%24filter=OrderStatusName+eq+'Started'&filterLogic=AND&%24skip=0&%24top=10&%24inlinecount=allpages&_=1376341370337
Everything works fine in terms of the data returned except Request.GetInLineCount returns null.
This 'kills' paging on the client side as the client ui elements don't know the total number of records.
There must be something wrong with how I'm constructing the new ODataQueryOptions object.
Please see my code below. Any help would be appreciated.
I suspect this post may contain some clues https://stackoverflow.com/a/16361875/1433194 but I'm stumped.
public PageResult<OrderVm> Get(ODataQueryOptions<OrderVm> options)
{
var incomingUri = options.Request.RequestUri.AbsoluteUri;
//manipulate the uri here to suit the entity model
//(related to a transformation needed for enumerable type OrderStatusId )
//e.g. the query string may include %24filter=OrderStatusName+eq+'Started'
//I manipulate this to %24filter=OrderStatusId+eq+'Started'
ODataQueryOptions<OrderVm> options2;
var newUri = incomingUri; //pretend it was manipulated as above
//Reconstruct the ODataQueryOptions with the modified Uri
var request = new HttpRequestMessage(HttpMethod.Get, newUri);
//construct a new options object using the new request object
options2 = new ODataQueryOptions<OrderVm>(options.Context, request);
//Extract a queryable from the repository. contents is an IQueryable<Order>
var contents = _unitOfWork.OrderRepository.Get(null, o => o.OrderByDescending(c => c.OrderId), "");
//project it onto the view model to be used in a grid for display purposes
//the following projections etc work fine and do not interfere with GetInlineCount if
//I avoid the step of constructing and using a new options object
var ds = contents.Select(o => new OrderVm
{
OrderId = o.OrderId,
OrderCode = o.OrderCode,
CustomerId = o.CustomerId,
AmountCharged = o.AmountCharged,
CustomerName = o.Customer.FirstName + " " + o.Customer.LastName,
Donation = o.Donation,
OrderDate = o.OrderDate,
OrderStatusId = o.StatusId,
OrderStatusName = ""
});
//note the use of 'options2' here replacing the original 'options'
var settings = new ODataQuerySettings()
{
PageSize = options2.Top != null ? options2.Top.Value : 5
};
//apply the odata transformation
//note the use of 'options2' here replacing the original 'options'
IQueryable results = options2.ApplyTo(ds, settings);
//Update the field containing the string representation of the enum
foreach (OrderVm row in results)
{
row.OrderStatusName = row.OrderStatusId.ToString();
}
//get the total number of records in the result set
//THIS RETURNS NULL WHEN USING the 'options2' object - THIS IS MY PROBLEM
var count = Request.GetInlineCount();
//create the PageResult object
var pr = new PageResult<OrderVm>(
results as IEnumerable<OrderVm>,
Request.GetNextPageLink(),
count
);
return pr;
}
EDIT
So the corrected code should read
//create the PageResult object
var pr = new PageResult<OrderVm>(
results as IEnumerable<OrderVm>,
request.GetNextPageLink(),
request.GetInlineCount();
);
return pr;
EDIT
Avoided the need for a string transformation of the enum in the controller method by applying a Json transformation to the OrderStatusId property (an enum) of the OrderVm class
[JsonConverter(typeof(StringEnumConverter))]
public OrderStatus OrderStatusId { get; set; }
This does away with the foreach loop.
InlineCount would be present only when the client asks for it through the $inlinecount query option.
In your modify uri logic add the query option $inlinecount=allpages if it is not already present.
Also, there is a minor bug in your code. The new ODataQueryOptions you are creating uses a new request where as in the GetInlineCount call, you are using the old Request. They are not the same.
It should be,
var count = request.GetInlineCount(); // use the new request that your created, as that is what you applied the query to.
I am currently trying to do retrieve text from sqlite. I see that the amount of data requested do come correctly, but content, on the other hand, seems to be in an incorrect format. I've tried some conversion:
var data:Array = sqls.getResult().data;
var stData:String = String(data[0]);
Alert.show(stData); // <--- displays "[object Object]"
String conversion does not seem to do what I want. I simply want the text from the sqlite database. How can I convert the [object Object] to the correct string in this case?
Irrespective of what rows are returned (with(out)) specifying columns, unless the itemClass property of the SQLStatement is defined, it will always return an anonymous object. This is essentially how remoting works with AMF.
There are two things you can do (depending on the complexity of your project):
Specify an SQLStatement.itemClass - this will define & popuplate the results of the return with public accessors (either var or get/set) with the same name as the column name.
If left as anonymous - the column names are attached to the object in which you iterate the object just as you would if it was defined.
Super basic example:
//SQL table schema
CREATE TABLE accounts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
num INTEGER NOT NULL,
name TEXT NOT NULL,
last_update DATE
);
//Define an Account class:
public class Account {
public var id:int;
public var num:int;
public var name:String;
public var last_update:Date;
}
//A statement to execute to get all accounts returned as an array of "Account"
var statement:SQLStatement = new SQLStatement();
statement.sqlConnection = myConn;
statement.itemClass = Account;
statement.text = 'SELECT * FROM accounts';
statement.addEventListener(SQLEvent.RESULT, onResults);
statement.execute();
protected function onResults(event:SQLEvent):void
{
var statement:SQLStatement = SQLStatement(event.currentTarget);
var results:SQLResult = statement.getResult();
for each (var account:Account in results)
{
//do something useful like populate a model, grid, etc...
}
}
//Anonymous objects would iterate much the same way -when an item class isn't defined
protected function onResults(event:SQLEvent):void
{
var statement:SQLStatement = SQLStatement(event.currentTarget);
var results:SQLResult = statement.getResult();
for each (var account:Object in results)
{
//our 'Object' will have properties: id, num, name, last_update
//do something useful like populate a model, grid, etc...
}
}
Please try with Objectutil.toString(); function which converts an object of any kind to a string.