Better management of cache objects of record data - asp.net

Is there a better way of doing this seems mundan to be retyping every var I think though automaper is to much for such a record however.
It works fine but I cant help but think could be neater I want to copy people cache also into the poi record
public POI FindPersonOrVessel(POI poiRecord ,int CaseId)
{
//each person that will be saved here will have a urn unique record number
var findPersoninCache = _context.PeopleCache.Where(w => w.PersonUrn == poiRecord.Id);
{
PeopleCache peopleCache = new PeopleCache();
peopleCache.FirstName = poiRecord.FirstName;
peopleCache.LastName = poiRecord.LastName;
peopleCache.DOB = poiRecord.DOB;
peopleCache.Age = poiRecord.Age;
peopleCache.Alias = peopleCache.Alias;
peopleCache.MISObjectId = CaseId;
peopleCache.FacialFeatures = poiRecord.FacialFeatures;
peopleCache.PersonUrn = poiRecord.Id;
_context.PeopleCache.Add(peopleCache);
_context.SaveChanges();
_toast.AddSuccessToastMessage("Saved Poi to Cache");
}
}

You could place the copy function into it's own method (passing into it whatever objects u need), then call that method in findpersonorvessel. On the surface its neat, the "messy details" are encapsulated.

Related

GMS2 returns instance_create_layer :: specified layer "text_layer" does not exist even though the layer exists how do i fix this?

heres the code
var _obj;
if (instance_exists(obj_text)) _obj = obj_txt_queued; else _obj = obj_text;
with (instance_create_layer(0, 0, "text_layer", _obj))
{
msg = argument[0];
if (instance_exists(other)) originInstance = other.id else originInstance = noone;
if (argument_count > 1) background = argument[1]; else background = 1;
}
with (obj_phae)
{ if (state != scr_player_state_lock)
{
lastState = state;
state = scr_player_state_lock;
}
}
[layers](https://i.stack.imgur.com/9u9tD.png)
I tried removing any extra rooms that were not needed and I tried changing the layer name to something else.
I also tried using var instance_create_layer() but that obviously didn't work
I'm a bit confused at this part:
with (instance_create_layer(0, 0, "text_layer", _obj))
Especially the with(), as that function will go through every object in the room if it sees an object within the parameter, since you suggested to create a new object with it, I'm surprised it doesn't create an infinite loop. Maybe it works, I've never tried it myself, but I think there's a more logical way to assign variables from one object to a newly created object.
Assuming you want to use the With() statement to address the variables within the _obj, I think you can manage something similair through this function:
var object = instance_create_layer(0, 0, "text_layer", _obj)
object.msg = argument[0];
object.originInstance = id
if (argument_count > 1) object.background = argument[1]; else object.background = 1;
It's probably a given at this point, but double-check that this part of code can only run if it's in the same room that has a layer called "text_layer"
In the worst case, you may also try out instance_create_depth() and use the build-in depth variable from the object instead of the layer names. Using depth is more flexible, but less organised than layers.

How to create multi items/records or save item/record array at one time in client script file

I want to create multiple records at the same time using client script. This is what I'm doing:
var ceateDatasource = app.datasources.Reservation.modes.create;
var newItem = ceateDatasource.item;
newItem.User = user; //'eric'
newItem.Description = description; //'000'
newItem.Location_Lab_fk = lab.value.Id; //'T'
newItem.Area_fk = area.value.Id; //'L'
newItem.Equipment_fk = equipment.value.Id; //'S'
for(var i = 0 ; i < 3; i ++) {
newItem.Start_Date = startDate;
newItem.Start_Hours = '03';
newItem.Start_Minutes = '00';
newItem.End_Date = startDate;
newItem.End_Hours = '23';
newItem.End_Minutes = '30';
// Create the new item
ceateDatasource.createItem();
}
But the result I'm getting is this one:
The three records are created but the only the first one has data. The other two records have empty values on their fields. How can I achieve this?
Thanks.
Update(2019-3-27):
I was able to make it work by putting everything inside the for loop block. However, I have another question.
Is there any method like the below sample code?
var recordData = [Data1, Data2, Data3]
var ceateDatasource;
var newItem = new Array(recordData.length) ;
for(var i = 0 ; i < recordData.length; i ++) {
ceateDatasource = app.datasources.Reservation.modes.create;
newItem[i] = ceateDatasource.item;
newItem[i].User = recordData[i].user;
newItem[i].Description = recordData[i].Description;
newItem[i].Location_Lab_fk = recordData[i].Location_Lab_fk;
newItem[i].Area_fk = recordData[i].Area_fk;
newItem[i].Equipment_fk = recordData[i].Equipment_fk;
newItem[i].Start_Date = recordData[i].Start_Date;
newItem[i].Start_Hours = recordData[i].Start_Hours;
newItem[i].Start_Minutes = recordData[i].Start_Minutes;
newItem[i].End_Date = recordData[i].End_Date;
newItem[i].End_Hours = recordData[i].End_Hours;
newItem[i].End_Minutes = recordData[i].End_Minutes;
}
// Create the new item
ceateDatasource.createItem();
First, it prepares an array 'newItem' and only calls 'ceateDatasource.createItem()' one time to save all new records(or items).
I try to use this method, but it only saves the last record 'newItem[3]'.
I need to write a callback function in 'ceateDatasource.createItem()' but Google App Maker always show a warning "Don't make functions within a loop". So, are there any methods to call 'createItem()' one time to save several records? Or are there some functions like 'array.push' which can be used?
Thanks.
As per AppMaker's official documentation:
A create datasource is a datasource used to create items in a particular data source. Its item property is always populated by a draft item which can be bound to or set programmatically.
What you are trying to do is create three items off the same draft item. That why you see the result you get. If you want to create multiple items, you need to create a draft item for each one, hence all you need to do is put all your code inside the for loop.
for(var i = 0 ; i < 3; i ++) {
var ceateDatasource = app.datasources.Reservation.modes.create;
var newItem = ceateDatasource.item;
newItem.User = user; //'eric'
newItem.Description = description; //'000'
newItem.Location_Lab_fk = lab.value.Id; //'T'
newItem.Area_fk = area.value.Id; //'L'
newItem.Equipment_fk = equipment.value.Id; //'S'
newItem.Start_Date = startDate;
newItem.Start_Hours = '03';
newItem.Start_Minutes = '00';
newItem.End_Date = startDate;
newItem.End_Hours = '23';
newItem.End_Minutes = '30';
// Create the new item
ceateDatasource.createItem();
}
If you want to save several records at the same time using client script, then what you are looking for is the Manual Save Mode. So all you have to do is go to your model's datasource and click on the checkbox "Manual Save Mode".
Then use the same code as above. The only difference is that in order to persist the changes to the server, you need to explicitly save changes. So all you have to do is add the following after the for loop block:
app.datasources.Reservation.saveChanges(function(){
//TODO: Callback handler
});

How to read, change and replace data with Firebase?

I'm trying to make a gambling website simulation, and I need to have a variable that stores the user's balance. This will change when they place a bet.
The variable is called "userbalance" and it set at 500 on Firebase. The user's bet is successfully stored on firebase. Therefore, I need to restrive this bet value again, and take it away from "userbalance", therefore updating their balance.
function storewager(){
var coinref = firebase.database().ref();
var coinwager = document.getElementById("coininput").value;
var userbalance =
coinref.child("coinbet").set(coinwager);
changeuserbal();
}
function changeuserbal(coinwager, userbalance){
var balref = firebase.database().ref().child('userbalance');
var coinwager = document.getElementById("coininput").value;
var userbalchg = balref - coinwager;
window.alert(balref);
balref.child("userbalance").set(userbalchg);
}
I can't understand why it is working correctly in storewager, but not in changeuserbal.
Here's the firebase database layout:
gambling-website-simulationaddclose
coinbet: "66" <--- this is the user bet, which is changed by storewager()
userbalance: 500 <--- I'm trying to take coinbet away from this
Thank you very much for your help, as when I can do this, I should be able to progress a good amount more.
EDIT
I've now managed to send the variable value, not the name To "userbalance". However, the calculation isn't correct. I believe the issue lies with the original value of "userbalance" not being referenced correctly.
Therefore, "userbalance" is just the wager but minus.
bal - coinwager = userbalchg ---> this is uploaded to "userbalance"
0 - coinwager = userbalchg ---> This is what I think is occuring
Here's the updated piece of my code:
function changeuserbal(coinwager){
var balref = firebase.database().ref().child("userbalance");
balref.once("value")
.then(function(snapshot){
var bal = snapshot.child("userbalance").val();
var coinwager = document.getElementById("coininput").value;
var userbalchg = bal - coinwager;
balref.set(userbalchg);
});
}

DynamoDB Xcode6 Swift using three columns as key

I am trying to use a DynamoDB table to store this data:
DartsPlayerInsultTable
CustomerId String
PlayerId String
PlayerInsult String
Using the method (concept, not code) described here:
https://java.awsblog.com/post/Tx3GYZEVGO924K4/The-DynamoDBMapper-Local-Secondary-Indexes-and-You
here:
http://mobile.awsblog.com/post/TxTCW7KW8BGZAF/Amazon-DynamoDB-on-Mobile-Part-4-Local-Secondary-Indexes
and here:
http://labs.journwe.com/2013/12/15/dynamodb-secondary-indexes/comment-page-1/#comment-116
I want to have multiple insult records per customer-player.
CustomerId is my Hash Key
PlayerId is my Range Key
and I a trying to use PlayerInsult in a key so that
a second PlayerInsult value inserts a second record
rather than replacing the existing one.
Have tried both Global and Secondary indexes for this,
but if I try to add a row with a new insult, it still
replaces the insult with the same customer-player key
rather than adding a new one.
Any suggestions on the best approach to use for this is
DynanoDB? Do I need to create a hybrid column for a range-key?
Trying to keep this simple...
class func createDartsPlayerInsultTable() -> BFTask {
let dynamoDB = AWSDynamoDB.defaultDynamoDB()
let hashKeyAttributeDefinition = AWSDynamoDBAttributeDefinition()
hashKeyAttributeDefinition.attributeName = "CustomerId"
hashKeyAttributeDefinition.attributeType = AWSDynamoDBScalarAttributeType.S
let hashKeySchemaElement = AWSDynamoDBKeySchemaElement()
hashKeySchemaElement.attributeName = "CustomerId"
hashKeySchemaElement.keyType = AWSDynamoDBKeyType.Hash
let rangeKeyAttributeDefinition = AWSDynamoDBAttributeDefinition()
rangeKeyAttributeDefinition.attributeName = "PlayerId"
rangeKeyAttributeDefinition.attributeType = AWSDynamoDBScalarAttributeType.S
let rangeKeySchemaElement = AWSDynamoDBKeySchemaElement()
rangeKeySchemaElement.attributeName = "PlayerId"
rangeKeySchemaElement.keyType = AWSDynamoDBKeyType.Range
/*
let indexRangeKeyAttributeDefinition = AWSDynamoDBAttributeDefinition()
indexRangeKeyAttributeDefinition.attributeName = "PlayerInsult"
indexRangeKeyAttributeDefinition.attributeType = AWSDynamoDBScalarAttributeType.S
let rangeKeySchemaElement = AWSDynamoDBKeySchemaElement()
rangeKeySchemaElement.attributeName = "PlayerId"
rangeKeySchemaElement.keyType = AWSDynamoDBKeyType.Range
let indexRangeKeyElement = AWSDynamoDBKeySchemaElement()
indexRangeKeyElement.attributeName = "PlayerInsult"
indexRangeKeyElement.keyType = AWSDynamoDBIndexRangeKeyType.
*/
//Add non-key attributes
let playerInsultAttrDef = AWSDynamoDBAttributeDefinition()
playerInsultAttrDef.attributeName = "PlayerInsult"
playerInsultAttrDef.attributeType = AWSDynamoDBScalarAttributeType.S
let provisionedThroughput = AWSDynamoDBProvisionedThroughput()
provisionedThroughput.readCapacityUnits = 5
provisionedThroughput.writeCapacityUnits = 5
// CREATE GLOBAL SECONDARY INDEX
/*
let gsi = AWSDynamoDBGlobalSecondaryIndex()
let gsiArray = NSMutableArray()
let gsiHashKeySchema = AWSDynamoDBKeySchemaElement()
gsiHashKeySchema.attributeName = "PlayerId"
gsiHashKeySchema.keyType = AWSDynamoDBKeyType.Hash
let gsiRangeKeySchema = AWSDynamoDBKeySchemaElement()
gsiRangeKeySchema.attributeName = "PlayerInsult"
gsiRangeKeySchema.keyType = AWSDynamoDBKeyType.Range
let gsiProjection = AWSDynamoDBProjection()
gsiProjection.projectionType = AWSDynamoDBProjectionType.All;
gsi.keySchema = [gsiHashKeySchema,gsiRangeKeySchema];
gsi.indexName = "PlayerInsult";
gsi.projection = gsiProjection;
gsi.provisionedThroughput = provisionedThroughput;
gsiArray .addObject(gsi)
*/
// CREATE LOCAL SECONDARY INDEX
let lsi = AWSDynamoDBLocalSecondaryIndex()
let lsiArray = NSMutableArray()
let lsiHashKeySchema = AWSDynamoDBKeySchemaElement()
lsiHashKeySchema.attributeName = "CustomerId"
lsiHashKeySchema.keyType = AWSDynamoDBKeyType.Hash
let lsiRangeKeySchema = AWSDynamoDBKeySchemaElement()
lsiRangeKeySchema.attributeName = "PlayerInsult"
lsiRangeKeySchema.keyType = AWSDynamoDBKeyType.Range
let lsiProjection = AWSDynamoDBProjection()
lsiProjection.projectionType = AWSDynamoDBProjectionType.All;
lsi.keySchema = [lsiHashKeySchema,lsiRangeKeySchema];
lsi.indexName = "PlayerInsult";
lsi.projection = lsiProjection;
//lsi.provisionedThroughput = provisionedThroughput;
lsiArray .addObject(lsi)
//Create TableInput
let createTableInput = AWSDynamoDBCreateTableInput()
createTableInput.tableName = DartsPlayerInsultTableName;
createTableInput.attributeDefinitions = [hashKeyAttributeDefinition, rangeKeyAttributeDefinition, playerInsultAttrDef]
//createTableInput.attributeDefinitions = [hashKeyAttributeDefinition, rangeKeyAttributeDefinition]
createTableInput.keySchema = [hashKeySchemaElement, rangeKeySchemaElement]
createTableInput.provisionedThroughput = provisionedThroughput
//createTableInput.globalSecondaryIndexes = gsiArray as [AnyObject]
createTableInput.localSecondaryIndexes = lsiArray as [AnyObject]
return dynamoDB.createTable(createTableInput).continueWithSuccessBlock({ (var task:BFTask!) -> AnyObject! in
if ((task.result) != nil) {
// Wait for up to 4 minutes until the table becomes ACTIVE.
let describeTableInput = AWSDynamoDBDescribeTableInput()
describeTableInput.tableName = DartsPlayerInsultTableName;
task = dynamoDB.describeTable(describeTableInput)
for var i = 0; i < 16; i++ {
task = task.continueWithSuccessBlock({ (task:BFTask!) -> AnyObject! in
let describeTableOutput:AWSDynamoDBDescribeTableOutput = task.result as! AWSDynamoDBDescribeTableOutput
let tableStatus = describeTableOutput.table.tableStatus
if tableStatus == AWSDynamoDBTableStatus.Active {
return task
}
sleep(15)
return dynamoDB .describeTable(describeTableInput)
})
}
}
return task
})
}
Putting this as an answer and not another comment in case it gets long...
It sounds like the average user's insults might fit into a single record. With the disclaimer that I know absolutely nothing about swift, this might at least be something relatively simple. Keep your customer and player keys. Before you persist the insults, turn the whole list into one big string using whatever version of join("|") swift has. When you fetch the record, do a split("|") to get your list back. (Just be a little judicious with your choice of separators, I'm only using "|" as an example, you don't want to choose something that might appear in an insult...)
There's going to be that one user with enough insults to take you over the 400kb object limit. Set a max list size constant in your code -- when you turn your lists into strings to persist them to dynamo, check the player's list length against that limit. If you exceed it, break your list into chunks of that size and use hash and range keys like ("foo", "bar"), ("foo", "bar1"), ("foo", "bar2"), etc. Yes, the first one does not have a bucket number at the end...
When you query for the data, just do a straight query first and assume you'll be in the good case (just "foo" and "bar", no other buckets). When you unpack that first list, check its length. If it's equal to your max list size constant, you know that you got a "bad" user and need to do a range query. That second one can use the hash key "foo" and the range "bar" to "bar9999". You will fetch back all those buckets with that range query. Unpack and concatenate all the lists.
This is a little gory, but it should also ultimately be straight ahead to code up. Hopefully it's still simple enough to hook into the patterns you mentioned.
What I decided to do was make a conventional dynamodb table with just one hash key, but the new hash key is a combined string of:
CustomerId + "|" + PlayerId
It is not too hard to maintain synchrony between players and insults tables because once a player is inserted into the player table, modifying the player name results in a new row being inserted. Thus, insults do not need to be modified if the player name changes. You only need to cleanup insults if a player is deleted.
This update behavior is just the way dynamodb works if you make Player name a hash key, which I did to insure they were unique.

. The An object with the same key already exists in the ObjectStateManagerObjectStateManager cannot track multiple objects with the same key

I am trying to simply update the entity object and I get this error.. All the googling on the error I did takes me to complex explanations... can anyone put it simply?
I am working of of this simple tutorial
http://aspalliance.com/1919_ASPNET_40_and_the_Entity_Framework_4__Part_2_Perform_CRUD_Operations_Using_the_Entity_Framework_4.5
else
{
//UPDATE
int iFid = Int32.Parse(fid.First().fid.ToString());
oFinancial.fid = iFid;
oFinancial.mainqtr = currentQuarter;
oFinancial.mainyear = currentYear;
oFinancial.qtr = Int32.Parse(currentQuarter);
oFinancial.year = Int32.Parse(currentYear);
oFinancial.updatedate = DateTime.Now;
// ObjectStateEntry ose = null;
// if (!dc.ObjectStateManager.TryGetObjectStateEntry(oFinancial.EntityKey, out ose))
// {
dc.financials.Attach(oFinancial);
// }
dc.ObjectStateManager.ChangeObjectState(oFinancial, System.Data.EntityState.Modified);
}
dc.SaveChanges();
here is what is higher up in the code that I use simple to get me the primary key value.. probably a better way but it works.
var fid = from x in dc.financials
where iPhaseID == x.phaseid &&
strTaskID == x.ftaskid &&
strFundType == x.fundtype &&
iCurrentQuarter == x.qtr &&
iCurrentYear == x.year
select x;
If the oFinancial object came from your dc and you never manually detached it, then there is no reason to call the Attach method or to mess with the ObjectStateManager. As long as the dc knows about the object (which it does unless you detach it), then the ObjectStateManager will keep track of any changes you make and update them accordingly when you call dc.SaveChanges().
EDIT: Here's a refactored version of what you posted, hope it helps:
else {
//UPDATE
// as long as oFinancial was never detatched after you retrieved
// it from the "dc", then you don't have to re-attach it. And
// you should never need to manipulate the primary key, unless it's
// not generated by the database, and you don't already have another
// object in the "dc" with the same primary key value.
int iFid = Int32.Parse(fid.First().fid.ToString());
oFinancial.fid = iFid;
oFinancial.mainqtr = currentQuarter;
oFinancial.mainyear = currentYear;
oFinancial.qtr = Int32.Parse(currentQuarter
oFinancial.year = Int32.Parse(currentYear);
oFinancial.updatedate = DateTime.Now;
}
dc.SaveChanges();
One other thing: if iFid is the primary key, then you shouldn't mess with it as long as this object came from the dc. I believe the problem is that you're resetting the primary key (iFid) to the same value of another object within the dc, and EF4 is barking because you can't have two rows with the same primary key value in a table.

Resources