In a EF Core model there are two classes, Company and Employee. 1 Company can have multiple Employees. I am wondering if I can add to reference navigation properties (collection of employees with different roles, i.e. manager role) referencing the same employees table and have EF Core figure out which employees to display in what property, depending on a property of the employee class (isManager, true/false).
See below, would this be possible?
public class Company
{
public int Id { get; set; }
public string Name { get; set; } = string.empty;
public virtual ICollection<Employee> Minions { get; set; }
public virtual ICollection<Employee> Managers { get; set; }
public Company()
{
Minions = new HashSet<Employee>();
Managers = new HashSet<Employee>();
}
}
public class Employee
{
public int Id { get; set; }
public string Name { get; set; } = string.empty;
public int CompanyId { get; set; }
public virtual Company Company { get; set; } = null!;
public bool IsManager { get; set; }
}
Id
Name
1
"MonkeyBizz Inc."
Id
Name
CompanyId
IsManager
1
"John Doe"
1
0
2
"Jane Doe"
1
0
3
"Skippy the Magnificent"
1
1
{
"id": 1,
"name": "MonkeyBizz Inc.",
"minions": [
{ "id": 1, "name": "John Doe", "companyId": 1, "isManager": false },
{ "id": 2, "name": "Jane Doe", "companyId": 1, "isManager": false }
],
"managers": [
{ "id": 3, "name": "Skippy the Magnificent", "companyId": 1, "isManager": true }
]
}
Related
My POCO classes:
[Table]
public class Product
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public List<CategoryProduct> CategoryProducts { get; set; }
}
public class CategoryProduct
{
public int CategoryId { get; set; }
public int ProductId { get; set; }
public Category Category { get; set; }
public Product Product { get; set; }
}
[Table]
public class Category
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public List<CategoryProduct> CategoryProducts { get; set; }
}
Here's a function for inserting new records:
async Task CreateProduct(Product dto)
{
await ctx.Products.AddAsync(dto);
await ctx.SaveChangesAsync();
}
In dto I pass the following JSON:
{
"name": "Gräff Stettin",
"categoryProducts": [{
"categoryId": 1,
"productId": 1,
"category": {
"id": 1,
"name": "Drinks"
}
}, {
"categoryId": 2,
"productId": 1,
"category": {
"id": 2,
"name": "Alcohol"
}
}
]
}
As a result, at SaveChangesAsync() I get an exception with message regarding attempt to insert already existing Category. Tracing shows the following query:
INSERT INTO "Category" ("Id", "Name") VALUES (#p0, #p1);
How should I change my CreateProduct() method to avoid attempts to add categories with already existing categoryId?
you can use AutoMapper and ignore category =
var config = new MapperConfiguration(cfg => cfg.CreateMap<categoryProductsDto,categoryProducts>())
.ForMember(u => u.Category, options => options.Ignore());
and use mapper =
var mapper = config.CreateMapper();
categoryProducts entity = mapper.Map<categoryProducts>(input);
await _categoryProductsRepository.InsertAndGetIdAsync(entity);
I was learning how to consume API's and got stuck with the error "Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'NbaApi.Models.Standard' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly." Thank you in advance!
I have this json
{
"_internal": {
"pubDateTime": "2020-04-03 13:11:16.692 EDT",
"igorPath": "S3,1585933850069,1585933857347|router,1585933857347,1585933857352|domUpdater,1585933857484,1585933875507|feedProducer,1585933875618,1585933885453",
"xslt": "NBA/xsl/league/roster/marty_active_players.xsl",
"xsltForceRecompile": "true",
"xsltInCache": "false",
"xsltCompileTimeMillis": "253",
"xsltTransformTimeMillis": "7800",
"consolidatedDomKey": "prod__transform__marty_active_players__1989425396229",
"endToEndTimeMillis": "35384"
},
"league": {
"standard": [
{
"firstName": "Steven",
"lastName": "Adams",
"temporaryDisplayName": "Adams, Steven",
"personId": "203500",
"teamId": "1610612760",
"jersey": "12",
"isActive": true,
"pos": "C",
"heightFeet": "6",
"heightInches": "11",
"heightMeters": "2.11",
"weightPounds": "265",
"weightKilograms": "120.2",
"dateOfBirthUTC": "1993-07-20",
"teamSitesOnly": {
"playerCode": "steven_adams",
"posFull": "Center",
"displayAffiliation": "Pittsburgh/New Zealand",
"freeAgentCode": ""
},
"teams": [
{
"teamId": "1610612760",
"seasonStart": "2013",
"seasonEnd": "2019"
}
],
"draft": {
"teamId": "1610612760",
"pickNum": "12",
"roundNum": "1",
"seasonYear": "2013"
},
"nbaDebutYear": "2013",
"yearsPro": "6",
"collegeName": "Pittsburgh",
"lastAffiliation": "Pittsburgh/New Zealand",
"country": "New Zealand"
}
]
}
}
I have these model classes
public class Data
{
public League League { get; set; }
}
public class League
{
public Standard Standard { get; set; }
}
public class Standard
{
public List<Player> players { get; set; }
}
public class Player
{
public string FirstName { get; set; }
public string LastName { get; set; }
//other parameters are also in the model
}
And I use this method to consume the api and pass it to the model
class Program
{
static void Main(string[] args)
{
var data = new List<Data>();
Player player = new Player();
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://data.nba.net/10s/prod/v1/2019/players.json");
//HTTP GET
var responseTask = client.GetAsync("");
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsAsync<List<Data>>();
readTask.Wait();
data = readTask.Result;
foreach (var item in data)
{
var league = item.League;
var standard = league.Standard;
var players = standard.players;
player = players.Where(p => p.LastName == "Adams").First();
}
}
else
{
throw new Exception(result.ReasonPhrase);
}
}
Console.WriteLine(player.LastName);
Console.ReadLine();
}
}
You need change your model as below
public class TeamSitesOnly
{
public string playerCode { get; set; }
public string posFull { get; set; }
public string displayAffiliation { get; set; }
public string freeAgentCode { get; set; }
}
public class Team
{
public string teamId { get; set; }
public string seasonStart { get; set; }
public string seasonEnd { get; set; }
}
public class Draft
{
public string teamId { get; set; }
public string pickNum { get; set; }
public string roundNum { get; set; }
public string seasonYear { get; set; }
}
public class Standard
{
public string firstName { get; set; }
public string lastName { get; set; }
public string temporaryDisplayName { get; set; }
public string personId { get; set; }
public string teamId { get; set; }
public string jersey { get; set; }
public bool isActive { get; set; }
public string pos { get; set; }
public string heightFeet { get; set; }
public string heightInches { get; set; }
public string heightMeters { get; set; }
public string weightPounds { get; set; }
public string weightKilograms { get; set; }
public string dateOfBirthUTC { get; set; }
public TeamSitesOnly teamSitesOnly { get; set; }
public List<Team> teams { get; set; }
public Draft draft { get; set; }
public string nbaDebutYear { get; set; }
public string yearsPro { get; set; }
public string collegeName { get; set; }
public string lastAffiliation { get; set; }
public string country { get; set; }
}
public class League
{
public List<Standard> standard { get; set; }
}
public class Data
{
public League league { get; set; }
}
You can use online tool to convert JSON object to C# class structure by http://json2csharp.com/
Change your model (since standard is an array, not an object):
public class League
{
public List<Player> Standard { get; set; }
}
The response object has structure:
{
"league": {
"standard": [...]
}
}
While your current model tries to deserialize:
{
"league": {
"standard": {
"players": [...]
}
}
}
I am trying to insert and update and delete (CRUD) an embedded object into existing Monogodb document,
assuming adding multiple addresses for a customer,
{
"_id":ObjectId("52ffc33cd85242f436000001"),
"contact": "987654321",
"dob": "01-01-1991",
"name": "Tom Benzamin",
"address": [
{
"building": "22 A, Indiana Apt",
"pincode": 123456,
"city": "Los Angeles",
"state": "California"
},
{
"building": "170 A, Acropolis Apt",
"pincode": 456789,
"city": "Chicago",
"state": "Illinois"
}
]
}
I can do it using command line (adding multiple address) , but through mvc core and I can only insert single address while inserting the document using InserOne, also I can update it using ReplaceOne , but I can add the second or third address.
here is my c# class and Interface (Service)
public class Customer
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
[BsonElement("contact")]
[Required]
public string Contact { get; set; }
[BsonElement("dob")]
[Required]
public string Dob { get; set; }
[BsonElement("name")]
public string Name { get; set; }
public Addresses Address { get; set; }
}
public class Addresses
{
public string Building { get; set; }
public string Pincode { get; set; }
public string City { get; set; }
public string State { get; set; }
}
}
and the service
public Customer Create(Customer c)
{
customers.InsertOne(c);
return c;
}
public void Update(string id, Customer c)
{
customers.ReplaceOne(cutomer => cutomer.Id == id, c);
}
How can I ignore a navigation property without using FluentAPI in the onModelCreating for the below example:
Table Layout:
My Classes are below. When I use my contact to get results for PmActionDetail, the WorkTask table includes the AssetTypeWorkTask results, which is not the desired result.
public partial class PmActionDetail
{
public int PmActionDetlId { get; set; }
public int? AssetTypeWorkTaskId { get; set; }
public virtual AssetTypeWorkTask AssetTypeWorkTask { get; set; }
}
public partial class AssetTypeWorkTask
{
public AssetTypeWorkTask()
{
AssetPmTypeWorkTask = new HashSet<AssetPmTypeWorkTask>();
}
public int Id { get; set; }
public int? AssetTypeId { get; set; }
public int WorkTaskId { get; set; }
public virtual AssetType AssetType { get; set; }
public virtual AssetWorkTask WorkTask { get; set; }
public virtual ICollection<AssetPmTypeWorkTask> AssetPmTypeWorkTask { get; set; }
public virtual ICollection<PmActionDetail> PmActionDetail { get; set; }
}
public partial class AssetType
{
public AssetType()
{
AssetTypeWorkTask = new HashSet<AssetTypeWorkTask>();
}
public int AssetTypeId { get; set; }
public string AssetTypeDescription { get; set; }
public virtual ICollection<AssetTypeWorkTask> AssetTypeWorkTask { get; set; }
}
public partial class AssetWorkTask
{
public int Id { get; set; }
public string Desc { get; set; }
public virtual ICollection<AssetTypeWorkTask> AssetTypeWorkTask { get; set; }
}
Here is the context query I am running:
return await _context.PmActionDetail.Include("AssetTypeWorkTask").Include("AssetTypeWorkTask.WorkTask")
.Include("AssetTypeWorkTask.AssetType").ToListAsync();
These are the results. I do not want to show the relationship for assetTypeWorkTask under "workTask". I understand why it is perhaps showing it, since it is part of the relationship. However, its not the result I need.
[
{
"pmActionDetlId": 6008,
"pmActionHeadId": 1517,
"assetTypeWorkTaskId": 29,
"assetTypeWorkTask": {
"id": 29,
"assetTypeId": 31,
"workTaskId": 8,
"assetType": {
"assetTypeId": 31,
"assetTypeCategory": "ROOM",
"assetTypeWorkTask": []
},
"workTask": {
"id": 8,
"desc": "PM",
"active": 1,
"assetTypeWorkTask": [
{
"id": 20,
"assetTypeId": 20,
"workTaskId": 8,
"assetType": {
"assetTypeId": 20,
"assetTypeCategory": "CASEGOODS",
}
},
{
"id": 21,
"assetTypeId": 21,
"workTaskId": 8,
"assetType": {
"assetTypeId": 21,
"assetTypeCategory": "APPLIANCES",
},
}
]
},
"assetPmTypeWorkTask": [],
"pmActionDetail": null
}
}
]
I want to get the response of the Model & reference model in json format from the Restful WCF service..
My model as below
// Role : User
[DataContract]
public class User
{
[DataMember]
public int Id {get; set;}
[DataMember]
public String Email { get; set; }
[DataMember]
public String Name { get; set; }
[DataMember]
public String Password { get; set; }
[DataMember]
public String Designation { get; set; }
}
// Role : Model
[DataContract]
public class Role
{
public Role()
{ }
[DataMember]
public int Id { get; set; }
[DataMember]
public String Name { get; set; }
}
// UserRole : Model
[DataContract]
public class UserRole
{
public UserRole()
{}
[DataMember]
public int Id { get; set; }
[DataMember]
public int UserId { get; set; }
[DataMember]
public int RoleId { get; set; }
[DataMember]
public int Level { get; set; }
}
Here what exactly I want to do.
when any client call method
Method: AssignRoleToUser with Form parameter "UserID" & "RoleId"
at that time I inserting new record to UserRole Entity and return object with json.
currently below JSON string output as response.
Current Output
{
"Id": 2,
"Level": 0,
"RoleId": 3,
"UserId": 2
}
I want like below
{
"Id": 2,
"Level": 0,
"RoleId": [
{
"Id": 5,
"Name": "Project Leader"
}
],
"UserId": [
{
"Designation": "System User",
"Email": "abhishek#domain.com",
"Gender": 0,
"Id": 1,
"Name": "System User",
"Password": null
}
]
}
Thanks