I am working with Azure CosmosDB. I am having below GetProgramsByStudentIDAsync method which needs to fetch all the programs associated to the studentID (Note that studentID is of type Guid).
using Microsoft.Azure.Cosmos;
using Microsoft.Azure.Cosmos.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Threading.Tasks;
public async Task<ProgramContainer> GetProgramsByStudentIDAsync(Guid[] studentIds)
{
var db = Client.GetDatabase(databaseId);
var programContainer = db.GetContainer(containerId);
using FeedIterator<ProgramContainer> feedIterator = programContainer.GetItemLinqQueryable<ProgramContainer>()
.Where(x => studentIds.Contains(x.StudentId)).ToFeedIterator(); //Giving me error at studentIds.Contains Please find the error details below:
CS1929: Guid[] does not contain a definition for 'Contains' and the best extension method overload requires a receiver of type
ProgramContainer class for reference:
public class ProgramContainer
{
public string ProgramName{ get; set; }
public string ProgramCode { get; set; }
public Guid StudentId { get; set; }
public bool IsActive { get; set; }
}
Please assist.Thanks in Advance!!!
Try explicitly casting to guid
using FeedIterator<ProgramContainer> feedIterator =
programContainer.GetItemLinqQueryable<ProgramContainer>()
.Where(x => studentIds.Contains((Guid)x.StudentId)).ToFeedIterator();
Related
Hi I want to insert multiple data and avoid duplicates in my programme. I have implemented the code to insert multiple data to mongoDB using asp.net core web api and it's working fine. I tried so many things but still I couldn't find a way to avoid duplicate records when inserting multiple records. Can you guys help me please :)
I want to avoid inserting duplicates by using employeeid.
this is my controller
using HelloApi.Models;
using HelloApi.Services;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace HelloApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Produces("application/json")]
public class EmployeeController : ControllerBase
{
private readonly EmployeeService _employeeService;
public EmployeeController(EmployeeService employeeService)
{
_employeeService = employeeService;
}
//.....................................Create..............................................
public Task Create(IEnumerable<Employee> employees)
{
return _employeeService.Create(employees);
}
}
}
This is my model class
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using System.ComponentModel.DataAnnotations;
namespace HelloApi.Models
{
public class Employee
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
[Key]
public string Id { get; set; }
[Required]
[BsonElement("employeeid")]
public string employeeid { get; set; }
[Required]
[BsonElement("firstname")]
public string firstname { get; set; }
[Required]
[BsonElement("lastname")]
public string lastname { get; set; }
[Required]
[BsonElement("age")]
public int age { get; set; }
[Required]
[BsonElement("address")]
public string address { get; set; }
[Required]
[BsonElement("telephone")]
public int telephone { get; set; }
}
}
This is my service class
using HelloApi.Models;
using MongoDB.Driver;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace HelloApi.Services
{
public class EmployeeService
{
private readonly IMongoCollection<Employee> _employee;
public EmployeeService(IHelloApiDatabaseSettings settings)
{
var client = new MongoClient(settings.ConnectionString);
var database = client.GetDatabase(settings.DatabaseName);
_employee = database.GetCollection<Employee>(settings.employeeCollectionName);
}
//.....................................Create..............................................
public Task Create(IEnumerable<Employee> employees)
{
return _employee.InsertManyAsync(employees);
}
}
}
This is the POST request in Postman and it is working fine but submit duplicates.
Really appreciate if you guys can help me with this :)
This Might be helpful. Use below InsertORUpdateEmployee function to find and update using employeeid.
public Task<string> Create(IEnumerable<Employee> employees)
{
return Task.Run(() =>
{
return InsertORUpdateEmployee(employees);
});
}
//Insert or Update Employees
private string InsertORUpdateEmployee(IEnumerable<Employee> employees)
{
try
{
foreach (Employee emp in employees)
{
var empId = emp.employeeid;
var DB = Client.GetDatabase("Employee");
var collection = DB.GetCollection<Employee>("EmployeeDetails");
//Find Employee using employeeid
var filter_id = Builders<Employee>.Filter.Eq("employeeid", empId);
var entity = collection.Find(filter_id).FirstOrDefault();
//Insert
if (entity == null)
{
collection.InsertOne(emp);
}
else
{
//Update
var update = collection.FindOneAndUpdateAsync(filter_id, Builders<Employee>.Update
.Set("firstname", emp.firstname)
.Set("lastname", emp.lastname)
.Set("age", emp.age)
.Set("address", emp.address)
.Set("telephone", emp.telephone));
}
}
return "Insert or Updated Succesfully";
}
catch (Exception ex)
{
return ex.ToString();
}
}
I think you need to add an extra step to declare your Id field as a Primary Key. [Key] should only work for RDBMS. For MongoDB i found another post here to define a field as a unique key.
(Actually MongoDB doesn't really allow for a Primary Key besides the auto-generated '_id' field, afaik, but you can create unique keys. )
Try looking through the answers posted here:
How to set a primary key in MongoDB?
It seems you need to create unique index on employeeId field to avoid duplicates :
db.employee.createIndex( { "employeeId": 1 }, { unique: true } )
I'm trying to make a webpage in c# .net core razorpages. Basically I want the values of a specific column from my postgresql table in a list, and then show these values in the select option in html. But I'm having some problems on the c# side. I get this error:
Cannot implicitly convert type 'System.Collections.Generic.List' to 'System.Collections.Generic.List<Project_Corona.Models.WorkspaceModel>' [Project_Corona]
Here is the code:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using Project_Corona.Database;
using Project_Corona.Models;
using Npgsql;
namespace Project_Corona.Controllers
{
public class HomeController : Controller
{
public IActionResult Employeepage()
{
var cs = Database.Database.Connector();
using var con = new NpgsqlConnection(cs);
con.Open();
List<WorkspaceModel> res = new List<WorkspaceModel>();
res = ("Select location FROM workspaces").ToList();
return View();
}
}
}
This is the code from WorkspaceModel.cs (if necessary)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using Project_Corona.Database;
using Project_Corona.Models;
using Npgsql;
namespace Project_Corona.Models
{
public class WorkspaceModel
{
[BindProperty]
public string LocationName { get; set; }
[BindProperty]
public string RoomName { get; set; }
[BindProperty]
public int SquareMeters { get; set; } = 1;
[BindProperty]
public int Lengthws { get; set; } = 1;
[BindProperty]
public int Widthws { get; set; } = 1;
}
}
Have you tried to use EntityFramework Core for PostgreSQL to query your database?
I created a small example here
Simply create a DbContext with your database server settings:
public class WorkspaceContext : DbContext
{
public DbSet<WorkspaceModel> Workspaces { get; set; }
//protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseInMemoryDatabase("inmemory");
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseNpgsql("Host=my_host;Database=my_db;Username=my_user;Password=my_pw");
}
... and call container.AddDbContext<WorkspaceContext>(); in your Dependency Injection configuration.
Now you can query your underlying database very easy by calling:
var res = ctx.Workspaces.Select(w => w.LocationName);
// var res = ctx.Workspaces.FromSqlRaw("Select location FROM workspaces");
Then you will get the result according to your sql statement: Select location FROM workspaces
This code is failing with the error: "Must declare the scalar value #prodID". Any suggestions?
using (var ctx = new StewieDataModel())
{
string productID = "81";
var techData = ctx.Database.SqlQuery<TechData>("dbo.usp_DS_GetTechData #prodID", productID).ToList();
}
Here's the model:
namespace DatasheetData
{
using System;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
public partial class StewieDataModel : DbContext
{
public StewieDataModel()
: base("name=StewieConnectionString")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
}
Here's the class I want to populate:
namespace DatasheetData
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("usp_DS_GetTechData")]
public partial class TechData
{
public string TestCategory { get; set; }
public string TestName { get; set; }
public string TestResultLabel { get; set; }
public string TestResult { get; set; }
public string TestMethod { get; set; }
}
}
Here's how I call it successfully in SSMS:
DECLARE #return_value int
EXEC #return_value = [dbo].[usp_DS_GetTechData]
#prodID = "81"
SELECT 'Return Value' = #return_value
GO
The SSMS results are four columns of VarChar data:
You need to pass the parameter as a SqlParameter object. Something like this should work:
var techData = ctx.Database.SqlQuery<TechData>(
"dbo.usp_DS_GetTechData #prodID",
new SqlParameter("prodID", productID)
).ToList();
A shorthand alternative to DavidG's correct answer is:
var techData = ctx.Database.SqlQuery<TechData>(
"dbo.usp_DS_GetTechData #prodID = {0}", productID).ToList();
as explained here.
I am still new to MVC, but I am starting to get a feel for the general picture however I still mixup things like namespace, or using and I THINK that may be the case here where I am mis-referencing something.
Question: I am trying to add an EmployeeInfo View, with a List template, with Model class: EmployeeInfo, with data context class: MoviesEntities
The auto-generation will not execute. When I right-click in Controller's method EmployeeInfo. I select the option "Add View", fill in the information, then hit add and during the scaffolding load screen it gives me the error as follows.
There was an error running the selected code generator: 'Unable to
retrieve metadata for 'WebApplication2.Models.EmployeeInfo'.'
My controller
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using WebApplication2.Entities;
using WebApplication2.Models;
namespace WebApplication2.Controllers
{
public class MoviesController : Controller
{
private MoviesEntities db = new MoviesEntities();
// GET: /Movies/
public ActionResult Index()
{
return View(db.Movies.ToList());
}
public ActionResult EmployeeInfo()
{
var query =
from m in db.Movies
join me in db.MovieEmployees
on m.ID equals me.movieID
join e in db.Employees
on me.employeeID equals e.ID
join r in db.Roles
on me.roleID equals r.ID
select new EmployeeInfo() {Name = e.Name, Role = r.RoleType, Birthday = e.Birthday };
return View(query.Distinct().ToList());
}
}
}
My context
//------------------------------------------------------------------------------
// <auto-generated> Built from database Movie </auto-generated>
//------------------------------------------------------------------------------
namespace WebApplication2.Entities
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using movieLayer;
using WebApplication2.Models;
public partial class MoviesEntities : DbContext
{
public MoviesEntities()
: base("name=MoviesEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Employee> Employees { get; set; }
public virtual DbSet<Location> Locations { get; set; }
public virtual DbSet<Movie> Movies { get; set; }
public virtual DbSet<MovieEmployee> MovieEmployees { get; set; }
public virtual DbSet<Role> Roles { get; set; }
public virtual DbSet<Show> Shows { get; set; }
public virtual DbSet<sysdiagram> sysdiagrams { get; set; }
public System.Data.Entity.DbSet<WebApplication2.Models.EmployeeInfo> EmployeeInfoes { get; set; }
}
}
Model of EmployeeInfo:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace WebApplication2.Models
{
public class EmployeeInfo
{
public EmployeeInfo() { }
public string Name { get; set; }
public string Role { get; set; }
public DateTime Birthday { get; set; }
}
}
What I did to solve this issue that I encountered when adding a scaffolded view by right clicking the controller action was to leave the "Data context class" field blank.
I'm not entirely sure as to why this works but I found this method from ASP.NET forums.
Make sure you rebuild your solution first. If you just added a new class, the scaffolding engine may not actually know about it, yet, if the project hasn't compiled.
If that doesn't work, close Visual Studio and restart. I have seen the scaffolding stuff just go wonky for no good reason in VS2012, and a restart will usually fix it.
The problem was the EmployeeInformation was just a "template" for the controller to dump it's data into from the query for the View.
EmployeeInformation was not actually an existing table, thus I had to make a model i.e. EmpleeInfoModels to hold the data, that was then passed to my custom View.
Method
public ActionResult EmployeeInformation()
{
var query =
from m in db.Movies
join me in db.MovieEmployees
on m.ID equals me.movieID
join e in db.Employees
on me.employeeID equals e.ID
join r in db.Roles
on me.roleID equals r.ID
select new EmployeeInfoModels() { Name = e.Name, RoleType = r.RoleType, Birthdate = e.Birthday, eID = e.ID };
return View(query.Distinct().ToList().Distinct());
}
Model
namespace WebApplication2.Models
{
public class EmployeeInfoModels
{
public int mID { get; set; }
public int eID { get; set; }
public string Name { get; set; }
public string RoleType { get; set; }
public DateTime Birthdate { get; set; }
}
}
And my View just brought in
#model IEnumerable<WebApplication2.Models.EmployeeInfoModels>
Adding one more tip: you may have this error if you have any configSource attributes in any of the elements in your web.config. I commented out all of the elements that contained a configSource attribute and then ran the scaffolding again and it worked like a charm. Once it was finished, I uncommented the elements in the web.config and I was all set.
Check your DataContextClass Option in Add View Pop winow and then correct the ConnectionString when adding your View from Controller
Refer Screenshot
.
Why do I get this exception? The code isn't the same but close to the 'demo' https://gist.github.com/1599013
Exception: MissingMethodException
Desc:
Method not found: 'System.Collections.Generic.IEnumerable1<System.Object> Dapper.SqlMapper.Query(System.Data.IDbConnection, System.String, System.Object, System.Data.IDbTransaction, Boolean, System.Nullable1, System.Nullable`1)'.
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Mail;
using Dapper;
using System.Data.SqlClient;
using MySql.Data.MySqlClient;
namespace daconsole2
{
class Program
{
class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime? LastPurchase { get; set; }
}
// container with all the tables
class MyDatabase : Database<MyDatabase>
{
public Table<Product> Products { get; set; }
}
//*/
static void Main(string[] args)
{
var cnn = new MySqlConnection("uid=name;pwd=pw;Port=3306;database=test");
cnn.Open();
var db = MyDatabase.Init(cnn, commandTimeout: 2);
//if(false)
db.Execute(#"create table Products (
Id int primary key,
Name varchar(20),
Description TEXT,
LastPurchase datetime)");
var productId = db.Products.Insert(new { Name = "Hello", Description = "Nothing" });
//var db = cnn;
Console.ReadKey();
}
}
}
We had this same problem, and it turned out to be that some of the projects in the solution were referencing different versions of Dapper.
For example, one project used a runtime version that showed v4.0.30319 in the Properties window.
Another project had a Dapper runtime version of v2.0.50727 (.NET 3.5).
As soon as I set them all to the v2.0.50727 version, this error went away.
*It should be noted that they both show File Version 1.12.0.0, so this is not a reliable way to tell them apart.