How to fetch the data from a helper class - c#

`Consider the input of the program as “inputObject” and you have a helper class with the name “objectService”. When you call any function from objectService helper class it will fetch the data from the database maintaining the output as multiple objects with same author. Fill the code in the Result function to perform the output using the details given below.
Below is my code`
inputObjects = [{id:1, idAuthor: 1, name: null, author: null}]
objectService {
// This function fetch an object from the database
// Input id is the id of the Object which you fetch data from database
Object Read(int id)
// This function fetch objects from the database
// Input ids are the ids of the Objects which you fetch data from database
List<Object> Read(List<int> ids)
}
class Object {
int id;
string name;
}
outputObjects = [{id:1, idAuthor: 1, name: "Object name", author: "author name"}]
private void Result (List<Object> objects) {
// Complete the code
}

Related

Is there a way to Batch Insert Records in google Firebase database under Windows forms?

the below code for inserting one record to google firebase using Firesharp
libarary for c# under windows forms ,but i want to insert bulk records at ones , like in sql SQL server
bulk.DestinationTableName = "test";
bulk.WriteToServer(table);
code for inserting one record to firebase
class Student
{
public string FullName { get; set; }
public string RollNo { get; set; }
public string Grade { get; set; }
public string Section { get; set; }
}
IFirebaseConfig ifc = new FirebaseConfig()
{
AuthSecret= "_AuthSecret",
BasePath= "_BasePath"
};
IFirebaseClient client;
Student std = new Student()
{
FullName=nameTbox.Text,
RollNo=rollTbox.Text,
Grade=gradeTbox.Text,
Section=secTbox.Text
};
var set = client.Set(#"Students/"+ rollTbox.Text,std);
The Firebase Database API does not have a specific operation for batch writes. If you want to write more data in one go, you'll just have to pass more data into one of the existing methods.
A few things to keep in mind there:
Calling Set on a location replaces all existing data at that location with the new data you pass in.
Calling Push writes the data you pass in on a new child location with a unique name under the location.
Calling Update updates the existing data in the location with the new data that you pass in.
For individual additional to a list, you'll typically use Push so that Firebase generates a unique name for the new data (starting with -L... at the moment).
For writing/updating multiple children you'll normally use Update, since that allows you to write the new data without disturbing the existing data. Firebase won't generate the keys for you in that case, so you'll have to ensure the unique keys for the data are present in the call to Update already.
The latter might look something like this:
var students = new Dictionary<string, Student>
{
{ Guid.NewGuid().ToString("N"), new Student() { ... } },
{ Guid.NewGuid().ToString("N"), new Student() { ... } },
{ Guid.NewGuid().ToString("N"), new Student() { ... } }
};
await _client.UpdateAsync("Students", students);
Thank you
I Solved My Problem by Using REST API using Post Method ,but firstly created an JASON for all my records to post it at once as Follows
// Instanciating with base URL
FirebaseDB firebaseDB = new FirebaseDB("Firebase Base link");
// Referring to Node with name "Teams"
FirebaseDB firebaseDBTeams = firebaseDB.Node("Teams");
var data = #"{
'Team-Awesome': {
'Members': {
'M1': {
'City': 'Giza',
'Name': 'Isaac'
},
'M2': {
'City': 'Cairo',
'Name': 'Be'
},
'M3': {
'City': 'France',
'Name': 'Pradeep'
}
}
}
}";
WriteLine("POST Request");
FirebaseResponse postResponse = firebaseDBTeams.Post(data);
WriteLine(postResponse.Success);
WriteLine();

Null fields on a partial update mutation on GraphQL .NET

At work, we're using EFCore on our data layer and graphql-dotnet to manage APIs requests, I'm having a problem updating some of our big objects using GraphQL mutations. When the user sends a partial update on the model, we would like to update on our database only the fields that actually were changed by the mutation. The problem we're having is that as we directly map the input to the entity, wheather some field was purposefully passed as null, or the field was not specified on the mutation at all, we get the property value as null. This way we can't send the changes to the database otherwise we would incorrectly update a bunch of fields to null.
So, we need a way to identify which fields are sent in a mutation and only update those. In JS this is achieved by checking if the property value is undefined, if the value is null we know that it was passed as null on purpose.
Some workarounds we've been thinking were using reflection on a Dictionary to update only the specified fields. But we would need to spread reflection to every single mutation. Another solution was to have a isChanged property to every nullable property on our model and change ir on the refered property setter, but... cmon...
I'm providing some code as example of this situation bellow:
Human class:
public class Human
{
public Id { get; set; }
public string Name { get; set; }
public string HomePlanet { get; set; }
}
GraphQL Type:
public class HumanType : ObjectGraphType<Human>
{
public HumanType()
{
Name = "Human";
Field(h => h.Id).Description("The id of the human.");
Field(h => h.Name, nullable: true).Description("The name of the human.");
Field(h => h.HomePlanet, nullable: true).Description("The home planet of the human.");
}
}
Input Type:
public class HumanInputType : InputObjectGraphType
{
public HumanInputType()
{
Name = "HumanInput";
Field<NonNullGraphType<StringGraphType>>("name");
//The problematic field
Field<StringGraphType>("homePlanet");
}
}
Human Mutation:
/// Example JSON request for an update mutation without HomePlanet
/// {
/// "query": "mutation ($human:HumanInput!){ createHuman(human: $human) { id name } }",
/// "variables": {
/// "human": {
/// "name": "Boba Fett"
/// }
/// }
/// }
///
public class StarWarsMutation : ObjectGraphType<object>
{
public StarWarsMutation(StarWarsRepository data)
{
Name = "Mutation";
Field<HumanType>(
"createOrUpdateHuman",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<HumanInputType>> {Name = "human"}
),
resolve: context =>
{
//After conversion human.HomePlanet is null. But it was not informed, we should keep what is on the database at the moment
var human = context.GetArgument<Human>("human");
//On EFCore the Update method is equivalent to an InsertOrUpdate method
return data.Update(human);
});
}
}
You could use JsonConvert.PopulateObject from the Newtonsoft Json library. On the mutation resolver instead of using GetArgument with my type, I'm using GetArgument<dynamic> and serializing it using JsonConvert.SerializeObject then by calling JsonConvert.PopulateObject I'm able to update only the fields that were informed.
public StarWarsMutation(StarWarsRepository data)
{
Name = "Mutation";
Field<HumanType>(
"createOrUpdateHuman",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<HumanInputType>> {Name = "human"}
),
resolve: context =>
{
//After conversion human.HomePlanet is null. But it was not informed, we should keep what is on the database at the moment
var human = context.GetArgument<dynamic>("human");
var humanDb = data.GetHuman(human["id"]);
var json = JsonConvert.SerializeObject(human);
JsonConvert.PopulateObject(json, humanDb);
//On EFCore the Update method is equivalent to an InsertOrUpdate method
return data.Update(humanDb);
});
}

Cannot display the list of names into the view

I have a list that I prepare in a ViewModel to take values from database table. The list assigned into a model class:
public class DType
{
public string DTName { get; set; }
}
And it get updated by the following method:
public static List<DType> GetDocTypesString(Entity DB, int RKey)
{
return DB.Database.SqlQuery<DType>(#"SELECT * FROM Names
WHERE NK = {0}", RKey).ToList();
}
And then I return the list (model) to the view to list the names into a select menu as the following:
The actual returned model to the view:
public List<DType> ihName { get; set; }
it gets populated by using the method above:
ihName = GetDocTypesString(DB, RKey);
And then, in the view, I use the below:
#Html.Partial("GettingNamesPartial", new ProjName.ViewModels.UploadingPartialViewModel
{
DropdownIHDocType = new SelectList(Model.ihEditorInstanceName)
})
The results are always like this:
Instead to displaying the actual names, the list (select) display:
ProjName.ViewModels.DType
ProjName.ViewModels.DType
ProjName.ViewModels.DType
ProjName.ViewModels.DType
The only thing that matches is the number of items is the same as the names on the database table.
Important Note:
Before trying to pull the names from the database, the list worked just fine by hard coding the names like the following:
DropdownIHDocType = new SelectList(new string[] { "Morgan", "Sam", "Shawn" })
ihName = GetDocTypesString(DB, RKey);
is your culprit. your getting a list of document types, not the variable name from each of those documents. basically your showing the class not its content. you need to get access to the actual document, then find the variable you need and assign that to ihName
so you're grabbing DType not DType.DTname which is what i assume your trying to list

Insert a document while auto incrementing a sequence field in MongoDB

Problem statement:
I have a collection in MongoDB that has a field with the type Int32. I would like to add a document to this collection. I need to increment the value by 1 for each insert as that field is indexed and must be unique.
Options:
[preferable] Increment the value on the DB side. That is, not specifying a new (higher) value. Just instruct MongoDB to auto increment upon insert.
Reading first. Executing a find query against the DB to find the current (before insert) highest value first, incrementing in memory, and inserting the new doc. This might fail due to racing conditions (the operation is not atomic).
keeping an index counter in memory. Not an option for me as there are multiple apps writing to the same collection (legacy limitation).
Other Ideas?
Example:
{
_id: ....
index: 123,
open: true
}
await collection.InsertOneAsync(record.ToBsonDocument());
The new doc inserted should have index value of 124
Language:
C#
Questions:
Can you provide a sample code (C#) to achieve the first option?
Extra info:
I do not have access to the code of the other app (which keeps its own index number). So having another collection and adding an sequence resolver function will not work as this will trigger a change to the legacy app.
MongoDB has a default tutorial on how to achieve that here
1 - Create a counters collections and insert the id there:
db.counters.insert(
{
_id: "userid",
seq: 0
}
)
2 - Create a custom function to retrieve the next value:
function getNextSequence(name) {
var ret = db.counters.findAndModify(
{
query: { _id: name },
update: { $inc: { seq: 1 } },
new: true
}
);
return ret.seq;
}
Use the getNextSequence to retrieve the next value:
db.users.insert(
{
_id: getNextSequence("userid"),
name: "Sarah C."
}
)
db.users.insert(
{
_id: getNextSequence("userid"),
name: "Bob D."
}
)
I had to do this in a project using MongoDB C# Driver.
Here's what I did: I created a separated collection called Sequence, with the name and value of it and I also created a repository for it.
Here is the code of class Sequence:
public class Sequence
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
[BsonElement("_id")]
public string Id { get; set; }
public string SequenceName { get; set; }
public int SequenceValue { get; set; }
}
And now the code of the method to generate the sequence value:
public class SequenceRepository
{
protected readonly IMongoDatabase _database;
protected readonly IMongoCollection<Sequence> _collection;
public SequenceRepository(IMongoDatabase database)
{
_database = database;
_colecao = _database.GetCollection<Sequence>(typeof(Sequence).Name);
}
public int GetSequenceValue(string sequenceName)
{
var filter = Builders<Sequence>.Filter.Eq(s => s.SequenceName, sequenceName);
var update = Builders<Sequence>.Update.Inc(s => s.SequenceValue , 1);
var result = _colecao.FindOneAndUpdate(filter, update, new FindOneAndUpdateOptions<Sequence, Sequence> { IsUpsert = true, ReturnDocument = ReturnDocument.After });
return result.SequenceValue;
}
}
Finally I called this method before insert some document:
public void Inserir(Order order)
{
order.Code = new SequenceRepository(_database).GetSequenceValue("orderSequence");
_collection.InsertOne(order);
}
You can create a Mongo Sequence in a separate collection counter
db.counter.insert({ _id: "mySeq", seq: 0 })
You can encapsulate sequence logic in a simple function like this
function getNextMySeq(name) {
var ret = db.counter.findAndModify({
query: { _id: name },
update: { $inc: { seq: 1 } },
new: true
});
return ret.seq;
}
Now simply use the function call during the insert
db.collection.insert({
index: getNextMySeq("mySeq")
})

Getting serialization exception when storing a list of object to session variable

I have a form which I want to store input field values to session variables. The form is used to create new user: an admin user would put in an username of new user, go to next page to add other info, and then create the user. So, I want to store the info they put on the first page to session variables to be able to use it later. Problem is that I'm getting a serialization exception.
This is the ajax I'm using, when going from first page to second page:
function holdUserData() {
//pass in username and a list of club IDs
var data = {
username: $('#tbUsername').val(),
clubs: this.clubs
};
$.ajax({
type: "POST",
url: '/Users/GoManageClub', //store in GoManageClub controller
data: data,
success: function (data) {
//redirect to ManageClubAccess controller when done
window.location = '/Users/ManagClubAccess';
}
})
}
And my GoManageClub controller, storing the data to session:
[HttpPost]
public ActionResult GoManagePolicy(string username, List<ClubVM> clubs)
{
Session["Username"] = username;
Session["Clubs"] = clubs;
return this.Json(new { success = true });
}
When I only store the username string, there are no problems and the variable is successfully stored. But when I'm storing the List<ClubVM>, I get the serialization exception:
Type 'myOrganization.ClubVM' in Assembly 'myorg, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable
My ClubVM:
public class ClubVM
{
public int ID { get; set; }
/* ... */
}
What should I do so I can save List<ClubVM> clubs?
The class to be serialized needs a Serializable attribute.
This indicates that you intend for the class to be serialized (stored as set of bytes.) That's what happens when you save an object to Session. Depending on the implementation of Session the object could be stored in memory or it could be saved to a database.
[Serializable()]
public class ClubVM
{
public int ID { get; set; }
/* ... */
}
Value types like int are already serializable. But if ClubVM contains references to other types then those types must also be serializable unless you mark them with a NonSerialized attribute. And so on. But if you mark something NonSerialized that means that when you deserialize the object (retrieve it from Session) that property will be missing because it wasn't included when the rest of the object was serialized.

Categories

Resources