Debugging MongoDB in C# - c#

I just started off with programming in C#. I'm using Visual Studio to make a Mongo database and followed a tutorial to get the following:
using System;
using System.Collections.Generic;
using System.Text;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
namespace NetCoreWeb.Repositories
{
public class BreakoutStrategyConfig
{
[BsonElement("id")]
public ObjectId id { get; set; }
[BsonElement("stock")]
public string stock { get; set; }
[BsonElement("trade_limit")]
public int trade_limit { get; set; }
[BsonElement("interval")]
public double interval { get; set; }
[BsonElement("exit_pl")]
public double exit_pl { get; set; }
}
}
This is the implementation:
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;
namespace NetCoreWeb.Repositories
{
public class BreakoutStrategyConfigImpl : IBreakoutStrategyConfig
{
private readonly IMongoDatabase _db;
public BreakoutStrategyConfigImpl()
{
MongoClient client = new MongoClient("mongodb://mymongo:27017");
_db = client.GetDatabase("BreakoutStrategyConfig");
}
public ICollection<BreakoutStrategyConfig> GetAllBreakoutStrategyConfigs()
{
List<BreakoutStrategyConfig> configs = new List<BreakoutStrategyConfig>();
var cursor = _db.GetCollection<BreakoutStrategyConfig>("BreakoutStrategyConfigs").Find(new BsonDocument()).ToCursor();
foreach (var document in cursor.ToEnumerable())
{
configs.Add(document);
}
return configs;
}
public BreakoutStrategyConfig GetBreakoutStrategyConfigById(ObjectId id)
{
return _db.GetCollection<BreakoutStrategyConfig>("BreakoutStrategyConfigs").Find(config => config.id == id).FirstOrDefault();
}
public void AddBreakoutStrategyConfig(BreakoutStrategyConfig config)
{
_db.GetCollection<BreakoutStrategyConfig>("BreakoutStrategyConfigs").InsertOne(config);
}
public void DeleteBreakoutStrategyConfig(ObjectId id)
{
_db.GetCollection<BreakoutStrategyConfig>("BreakoutStrategyConfigs").DeleteOne(config => config.id == id);
}
public void UpdateBreakoutStrategyConfig(BreakoutStrategyConfig config)
{
_db.GetCollection<BreakoutStrategyConfig>("BreakoutStrategyConfigs").ReplaceOneAsync(n => n.id.Equals(config.id)
, config
, new UpdateOptions { IsUpsert = true });
}
}
}
My problem is pretty simple: I made the classes and tables but I'm not sure how to test this.
How can I see a list of collections a documents in the database?
Do I write a script in Program.cs (automatically created)?
Essentially, I just need to see if this works.

Did you mean that collection and database is created by your code or not?
if yes, you don't need to manually run the script to create db and collection.
If DB / collection is not exist then mongodb will automatically creates it.

Related

Program crashed when triggering Http Function to query entity state?

I am a starter in Azure Functions and durable Entities. I want to do the following things:
Create a durable entity and it has a state called systemList;
Create a queue trigger function to consume messages in my queue and store them in the entity state I just created.
create a http trigger function to get the current state of the entity;
And I met some problems in the 3rd step.
The code is as follows:
//HttpTriggerFunction.cs:
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using System.Net.Http;
using System.Net;
using Newtonsoft.Json.Linq;
namespace **.Function
{
public static class HttpTriggerQueryEntity
{
[FunctionName("QueryEntity")]
public static async Task<HttpResponseMessage> Run(
[HttpTrigger(AuthorizationLevel.Function)] HttpRequestMessage req,
[DurableClient] IDurableEntityClient client)
{
var entityId = new EntityId(nameof(ProcessingListEntity), "processing_message_total");
EntityStateResponse<JObject> stateResponse = await client.ReadEntityStateAsync<JObject>(entityId);
//await client.SignalEntityAsync(entityId, "Empty");
return req.CreateResponse(HttpStatusCode.OK,stateResponse.EntityState);
}
}
}
//blockData.cs
#nullable enable
using System;
namespace **.Function
{
public class BlockData
{
public string? id { get; set; }
public string? SessionId { get; set; }
public string? MachineId { get; set; }
public DateTime? Start { get; set; }
public DateTime? End { get; set; }
public string? Activity {get; set;}
public string? BlobId { get; set; }
}
}
//Entity.cs
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using System.Collections.Generic;
namespace **.Function
{
[JsonObject(MemberSerialization.OptIn)]
public class ProcessingListEntity
{
public ProcessingListEntity(){
systemList = new Dictionary<string, BlockData>();
}
[JsonProperty("systemList")]
public Dictionary<string, BlockData> systemList {get; set;}
public void Add(BlockData blockData) {
if (!this.systemList.ContainsKey(blockData.MachineId)) {
this.systemList.Add(blockData.MachineId, blockData);
return;
}
else {
this.systemList[blockData.MachineId].Start = blockData.Start;
this.systemList[blockData.MachineId].End = blockData.End;
}
}
public void Empty() => this.systemList = new Dictionary<string, BlockData>();
public Dictionary<string, BlockData> Get() => this.systemList;
[FunctionName(nameof(ProcessingListEntity))]
public static Task Run([EntityTrigger] IDurableEntityContext ctx)
=> ctx.DispatchAsync<ProcessingListEntity>();
}
}
But when I run it in my local environment and send Http query to it, the program stop. But when I changed the following line in HttpTriggerFunction.cs:
return req.CreateResponse(HttpStatusCode.OK,stateResponse.EntityState);
to
return req.CreateResponse(HttpStatusCode.OK,stateResponse.EntityState + "");
It can run and return the required string. But what I want to return is Json string.
So what can I do to fix my code? Thank you!
You can do is serialize the object and encode it and then send it.
So instead of createResponse return a HttpResponseMessage.
First you need to add packages such as:
using system.text;
using NewtonSoft.Json;
Then you can return :
return new HttpResponseMessage(HttpStatusCode.OK){Content = new StringContent(JsonConvert.SerializeOject(stateResponse.EntityState , Formating.Indented),Encoding.UTF8,"Response.json")}:
Refer the following article by Callon Campbell
Refer the following documentation.

CRUD WEB API with entity framework

I started develop my project - web application with Database. I used WEB API with entity framework
I need CRUD operations realize in my project.
Read - work fine
But I don't know how realize Create, Update, Delete; I don't have enough experience and be glad yours advice.
I tried realize good architecture of my application - using repository pattern and fabric pattern. If you have advice in architecture of my project , I'll be grateful you.
I don't know how realize it in value controller and repository, could you help please?
Attach my code:
Repository
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WebAPI
{
public class CustomerRepository
{
public IQueryable<Customer> GetAllCustomers()
{
DevelopersEntities dev = new DevelopersEntities();
return dev.Customers;
}
public IQueryable<Customer> GetAllCustomers(int id)
{
DevelopersEntities dev = new DevelopersEntities();
return dev.Customers.Where(c=>c.Id==id).Select(e=>e);
}
public IQueryable<Customer> DeleteCustomer(int id)
{
DevelopersEntities dev = new DevelopersEntities();
return dev.Customers.Remove(id);
}
public IQueryable<Customer> CreateCustomer()
{
DevelopersEntities dev = new DevelopersEntities();
}
public IQueryable<Customer> UpdateCustomer(int id)
{
DevelopersEntities dev = new DevelopersEntities();
}
}
}
Customer model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WebAPI;
namespace DevelopersWeb.Models
{
public class CustomerModel
{
public int CustomerId { get; set; }
public string CustomerName { get; set; }
public IEnumerable<HardwareModel> Hardware { get; set; }
public IEnumerable<SoftwareModel> Software { get; set; }
}
}
Harware Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DevelopersWeb.Models
{
public class HardwareModel
{
public int HardwareId { get; set; }
public string HardwareName { get; set; }
}
}
Software Model
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DevelopersWeb.Models
{
public class SoftwareModel
{
public int SoftwareId { get; set; }
public string SoftwareName { get; set; }
}
}
Model Factory
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using WebAPI;
namespace DevelopersWeb.Models
{
public class ModelFactory
{
public CustomerModel Create(Customer customer)
{
return new CustomerModel()
{
CustomerId = customer.Id,
CustomerName = customer.Name,
Hardware = customer.HardWares.Select(h=>Create(h)),
Software = customer.Softwares.Select(c=>Create(c))
};
}
public HardwareModel Create(HardWare hardware)
{
return new HardwareModel()
{
HardwareId = hardware.HardWareId,
HardwareName = hardware.HardWareName,
};
}
public SoftwareModel Create(Software software)
{
return new SoftwareModel()
{
SoftwareId = software.SoftwareId,
SoftwareName = software.SoftwareName
};
}
}
}
Value Controller
using DevelopersWeb.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using WebAPI;
namespace DevelopersWeb.Controllers
{
public class ValuesController : ApiController
{
ModelFactory _modelFactory;
public ValuesController()
{
_modelFactory = new ModelFactory();
}
// GET api/values
public IEnumerable<CustomerModel> Get()
{
CustomerRepository cr = new CustomerRepository();
return cr.GetAllCustomers().ToList().Select(c=> _modelFactory.Create(c));
}
// GET api/values/5
public string Get(int id)
{
return "xxx";
}
// POST api/values
public void Post([FromBody]string value)
{
}
// PUT api/values/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/values/5
public void Delete(int id)
{
}
}
}
Here is how you should save customer object:
public void CreateCustomer(Customer customer)
{
DevelopersEntities dev = new DevelopersEntities();
dev.Customers.Add(customer)
dev.SaveChanges();
}
Here is you api action:
// POST api/values
public void Post([FromBody]CustomerModel customerModel)
{
//Here you should transform CustomerModel object to customerEntity
CustomerRepository cr = new CustomerRepository();
cr.CreateCusomer(customer);
return Ok();
}
You should think about using Dependency Injection pattern here as well.

How can I use latest MongoDB C# Driver to delete an element within a nested array of complex array objects based on multiple conditions?

The overall goal is to be able to perform a lookup of a meal based on the userid, and mealid. If that item is found, I want to be able to delete only the entire element that matches both the userid and mealid.
Currently, After sending the request object via postman in a post request, I have tried to write a variation of queries using the C# to create a builder object, and then filter to find the specific array object, and finally delete the array object if there is a match on both userid and mealid. Initially, I was getting the issue where the entire element was not being deleted, but only the interal array element that is nested inside of the element was being (not deleted, but set back to null values). However, now the issue is that the entire array element is not being deleted at all and i'm getting the following error.
BsonArraySerializer Error from Visual Studio
Can someone please help me to resolve this issue?
Here is a sample object that I'm sending via postman that I'm trying to delete:
Sample Postman POST request with Body data
Here is an example image of data that I'm trying to delete:
Sample Image of Json Array Elemet I'm trying to delete
You will need MongoDb Compass or Atlas, .NET Core 3.1, MongoDB C# Driver 2.0, Postman, and .NET Core 3.1 WebApi Project/Solution in order to help solve this issue.
Below, is the code that is needed to replicate the issue:
Startup.cs
Add this line of code to the Configuration method of this file
services.AddScoped<IMealsRepository, MealsRepository>();
Add this line to the ConfigureServices Method
services.AddSingleton(sp =>
sp.GetRequiredService<IOptions<DatabaseSettings>>().Value);
appSettings.json
Add these lines of code to this file
"DatabaseSettings": {
"ConnectionString": "your connection string to MongoDb"
}
Database Settings.cs
public class DatabaseSettings
{
public string ConnectionString { get; set; }
}
MealPlanModel.cs:
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
public class MealPlanModel
{
#region MealPlanModel fields
[BsonElement("userid")]
public int? UserId { get; set; }
[BsonElement("mealid")]
public int? MealId { get; set; }
[BsonElement("mealname")]
public string MealName { get; set; }
[BsonElement("mealimage")]
public string MealImage { get; set; }
[BsonElement("foods")]
public FoodModel[] Foods { get; set; }
[BsonElement("totalcalories")]
public double TotalCalories { get; set; }
[BsonElement("totalprotein")]
public double TotalProtein { get; set; }
[BsonElement("totalcarbs")]
public double TotalCarbs { get; set; }
[BsonElement("totalfat")]
public double TotalFat { get; set; }
[BsonElement("totalsugar")]
public double TotalSugar { get; set; }
[BsonElement("totalfiber")]
public double TotalFiber { get; set; }
#endregion
#region MealPlanModel ctor
public MealPlanModel()
{
}
public MealPlanModel(int userid, int mealid)
{
UserId = userid;
MealId = mealid;
}
}
MealPlanDto.cs
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using System.Collections.Generic;
public class MealPlanDto
{
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("meals")]
public List<MealPlanModel> MealPlans { get; set; }
}
**MealsController.cs:**
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
[Route("api/[controller]")]
[ApiController]
public class MealsController : ControllerBase
{
private readonly IMealsRepository _repo;
private readonly IMapper _mapper;
public MealsController(IMealsRepository repo, IMapper mapper)
{
_repo = repo;
_mapper = mapper;
}
[HttpGet, Route("CheckConnection")]
public async Task<IActionResult> CheckConnection()
{
var result = await _repo.CheckConnection();
if (result == null || result.Count <= 0)
return BadRequest("Failed to connect to database.");
return Ok("Database connection was successful");
}
[HttpPost("deletecustommeal")]
public async Task<IActionResult> DeleteCustomMealPlan(int id)
{
var requestBody = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync();
var mealPlanToDelete = JsonConvert.DeserializeObject<MealPlanModel>(requestBody);
MealPlanDto deleteMealPlan = new MealPlanDto();
deleteMealPlan.MealPlans = new List<MealPlanModel>();
deleteMealPlan.MealPlans.Add(mealPlanToDelete);
var result = await _repo.DeleteCustomMealPlanById(deleteMealPlan);
if (!result)
return BadRequest("Failed to delete meal");
return Ok("Successfully deleted meal plan");
}
}
MealsRepository.cs
using Microsoft.Extensions.Configuration;
using MongoDB.Bson;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
public class MealsRepository : IMealsRepository
{
private readonly MongoClient _client;
private readonly IMongoDatabase _database;
private readonly IMongoCollection<MealPlanDto> _userMealsCollection;
public MealsRepository(IConfiguration configuration)
{
_client = new
MongoClient(configuration.GetSection("DatabaseSettings").GetSection("ConnectionString").Value);
_database = _client.GetDatabase("MealsDb");
_userMealsCollection = _database.GetCollection<MealPlanDto>("meal");
}
public async Task<List<BsonDocument>> CheckConnection()
{
List<BsonDocument> list = await _database.ListCollections().ToListAsync();
var populatedList = (list != null && list.Count > 0) ? list : null;
return populatedList;
}
public async Task<bool> DeleteCustomMealPlanById(MealPlanDto mealPlanToDelete)
{
var builder = Builders<MealPlanDto>.Filter;
var filter = builder.Eq(x => x.MealPlans[0].UserId, mealPlanToDelete.MealPlans[0].UserId);
var update = Builders<MealPlanDto>.Update.PullFilter(
p => (IEnumerable<MealPlanModel>)p.MealPlans[0],
f => f.MealId.Value == mealPlanToDelete.MealPlans[0].MealId);
try
{
await _userMealsCollection.UpdateOneAsync(filter, update);
return true;
}
catch (Exception ex)
{
Console.WriteLine($"Failed to delete meal plan. {ex} occured.");
return false;
}
}
}
Thanks for all that attempted to find an answer to my question above, but I actually discovered a simple solution
I simply replaced the above method in the Repository.cs file with the following and it works like a charm
public bool DeleteCustomMealPlanForUserById(MealPlanModel mealPlanToDelete)
{
var result = _customUserMealsCollection.DeleteOne(p => p.MealPlans[0].UserId == mealPlanToDelete.UserId
&& p.MealPlans[0].MealId == mealPlanToDelete.MealId);
return result.DeletedCount != 0;
}

GetSnapshotAsync() never returning and I don't get any errors. How can I debug this issue?

I'm trying Firestore with the nugget package Google.Cloud.Firestore
I followed this intro CRUD with firestore
Using the debugger I can see that the execution of the program stops when trying to call the method Query.GetSnapshotAsync()
I want to get just a list of documents from a collection.
Controller
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web.Http;
using System.Web.Http.Results;
using FirestoreAPI.Domain.Restaurants;
using FirestoreAPI.Repository.Restaurants;
using System.Threading.Tasks;
namespace FirestoreAPI.Controllers
{
[RoutePrefix("api")]
public class RestaurantsController : ApiController
{
public RestaurantsController() { }
[HttpGet]
[Route("restaurants")]
public IHttpActionResult GetAllRestaurants()
{
//var restAggregate = new RestaurantsAggregate();
var restaurantsRepo = new RestaurantsRepo();
return new NegotiatedContentResult<Task<List<Restaurant>>>(
HttpStatusCode.OK,
restaurantsRepo.GetAllRestaurants(),
this
); ;
}
}
}
DataLayer
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
using Google.Cloud.Firestore;
namespace FirestoreAPI.Repository.Restaurants
{
public class RestaurantsRepo
{
//public FirestoreConn dbConn;
string projectId;
FirestoreDb firestoreDb;
public RestaurantsRepo()
{
//dbConn = new FirestoreConn();
string credentials = "C:\\Users\\ezequiel.lopez\\projects\\firestoredotnet\\FirestoreAPI\\firestoreapi-dca55-0be2f7d57f41.json";
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", credentials);
projectId = "firestoreapi-dca55";
firestoreDb = FirestoreDb.Create(projectId);
}
public async Task<List<Restaurant>> GetAllRestaurants()
{
//FirestoreDb fsDB = dbConn.GetFSConnection();
//Query query = fsDB.Collection("restaurants").OrderByDescending("avgRating").Limit(50);
Query query = firestoreDb.Collection("restaurants").OrderByDescending("avgRating").Limit(50);
QuerySnapshot restSnaps = await query.GetSnapshotAsync();
List<Restaurant> restaurants = new List<Restaurant>();
return restSnaps.Documents
.Where<DocumentSnapshot>(ds => ds.Exists)
.Select(ds => ds.ConvertTo<Restaurant>()).ToList();
}
}
}
Restaurant
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Google.Cloud.Firestore;
namespace FirestoreAPI.Repository.Restaurants
{
[FirestoreData]
public class Restaurant
{
[FirestoreProperty]
public decimal avgRating { get; set; }
[FirestoreProperty]
public string category { get; set; }
[FirestoreProperty]
public string city { get; set; }
[FirestoreProperty]
public string name { get; set; }
[FirestoreProperty]
public int numRatings { get; set; }
[FirestoreProperty]
public int price { get; set; }
}
}
I was having the same issue. Thing is, I was calling an async method from a synchronous one. It didn't work until I've made my caller method async and awaited for it.

How to delete item from SQLite PCL database on Xamarin.Forms?

I am using one of the Xamarin.Forms tutorials on SQLite database deployment to learn how to add, get and delete items from a mobile database. At the moment, I am not quite sure how to retrieve a the Id attribute from a database item in my table to pass it through the deleteData method. Basically, after I add in a certain amount of items, I would like to delete some of the data. I have implemented a button in my XAML binding pages but I need to know how to retrieve the Id attribute of certain items and pass them into the deleteData method I have created. Can anyone help me with this?
Here are the codes:
StudentDB.cs (database class)
using System;
using System.Linq;
using SQLite.Net;
using Xamarin.Forms;
using System.Collections.Generic;
namespace XamarinSqliteSample
{
public class StudentDB
{
private SQLiteConnection _sqlconnection;
public StudentDB ()
{
_sqlconnection = DependencyService.Get<ISQLite> ().GetConnection ();
_sqlconnection.CreateTable<Student> ();
}
public IEnumerable<Student> GetStudents()
{
return (from t in _sqlconnection.Table<Student> ()
select t).ToList ();
}
public Student GetStudent (int id)
{
return _sqlconnection.Table<Student> ().FirstOrDefault (t => t.Id == id);
}
public void DeleteStudent(int id)
{
_sqlconnection.Delete<Student>(id);
}
public void AddStudent(Student student)
{
_sqlconnection.Insert(student);
}
}
}
Student.cs (item attributes for database table)
using System;
using SQLite.Net.Attributes;
namespace XamarinSqliteSample
{
public class Student
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
public Student ()
{
}
}
}
Register.xaml.cs (C# page to create methods to that manipulate data)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace XamarinSqliteSample
{
public partial class Register : ContentPage
{
public StudentDB _studentdb;
public Student student;
public Register()
{
InitializeComponent();
}
public void adddata(object s, EventArgs args)
{
student = new Student();
_studentdb = new StudentDB();
student.Name = name.Text;
student.Address = address.Text;
student.Phone = phone.Text;
student.Id++;
_studentdb.AddStudent(student);
}
public void Showdata(object sender, EventArgs args)
{
Navigation.PushModalAsync(new StudentList());
}
}
}
StudentList.xaml.cs (C# page to populate list view with database items)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace XamarinSqliteSample
{
public partial class StudentList : ContentPage
{
public StudentDB _database;
public Student student;
public StudentList()
{
InitializeComponent();
_database = new StudentDB();
var students = _database.GetStudents();
StudentListView.ItemsSource = students;
}
public void deleteData(object s, EventArgs args)
{
_database = new StudentDB ();
_database.DeleteStudent (//Id attribute is passed in here);
}
}
It depends on how you trigger deleteData, but you'll probably want to use StudentListView.ItemSelected, which should be one of your Student objects.

Categories

Resources