Merge entities in Entity Framework 6 - c#

I have these entities which represent Menu and Labels SQL tables:
public class Menu
{
public int IdMenu { get; set; }
public int IdLabel { get; set; }
}
public class Label
{
public int IdLabel { get; set; }
public string Value { get; set; }
}
In a controller I have this method:
public IActionResult GetAll()
{
var menu = _service.GetAll();
var model = _mapper.Map<IList<MenuModel>>(menu);
return Ok(model);
}
but obviously, it gives me only IdMenu and IdLabel for each menu item.
What should I do to let it give me IdMenu and Value of Label?
Update n. 1:
Entities:
public class MenuPadre_EL
{
[Key]
public int IdMenuPadre { get; set; }
public int IdEtichetta { get; set; }
public string Icona { get; set; }
public MenuPadreUtente_EL menuPadreUtente { get; set; }
}
public class MenuPadreUtente_EL
{
public int IdMenuPadreUtente { get; set; }
public int IdUtente { get; set; }
public int IdMenuPadre { get; set; }
public MenuPadre_EL menuPadre { get; set; }
}
DataContext:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Etichetta>().HasKey(e => new { e.IdEtichetta, e.Lingua });
modelBuilder.Entity<MenuPadreUtente_EL>().HasKey(m => new { m.IdMenuPadre, m.IdUtente });
modelBuilder.Entity<MenuPadre_EL>()
.HasOne(mpu => mpu.menuPadreUtente)
.WithOne(mp => mp.menuPadre)
.HasForeignKey<MenuPadreUtente_EL>(mpu => mpu.IdMenuPadre);
}
Model:
public class MenuPadreUtente_ELModel
{
public int IdMenuPadreUtente { get; set; }
public int IdMenuPadre { get; set; }
public int IdUtente { get; set; }
public string Etichetta { get; set; }
public MenuPadre_EL menuPadre { get; set; }
}
API Output:
[
{
"idMenuPadreUtente": 1,
"idMenuPadre": 1,
"idUtente": 1,
"etichetta": null,
"menuPadre": null
}
]
why menuPadre is null?

You can do that as bellow:
[HttpGet]
public IActionResult GetAll()
{
var menu = menueList();
var lable = lableList();
var model = (from _menue in menu
join _lable in lable
on _menue.IdLabel equals _lable.IdLabel
select new
{
IdMenu = _menue.IdMenu,
Value = _lable.Value,
}).ToList();
return Ok(model);
}

Related

JSONpatch to remove item from ICollection

I am following TPH in my feature and I have these models which are mapped to tables in database
public class HrFormV1
{
public HrFormV1()
{
...
}
public HrFormV1(HrFormV1DTO form)
{
...
}
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string OrganizationId { get; set; }
public Organizations Organization { get; set; }
public List<HrFormSectionV1> FormSections { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
public HrFormType Type { get; set; }
public string CreatedById { get; set; }
public User CreatedBy { get; set; }
public static void DefineDbModel(ModelBuilder modelBuilder)
{
modelBuilder.Entity<HrFormV1>().Property(f => f.Id).ValueGeneratedOnAdd();
}
}
public class HrFormSectionV1
{
public string Id { get; set; }
public int Index { get; set; }
public string FormId { get; set; }
public HrFormV1 Form { get; set; }
public HrFormSectionV1()
{
...
}
public HrFormSectionV1(HrFormSectionV1DTO section)
{
...
BuildingComponents = section.BuildingComponents.Select(b => #switch[b.GetType()](b)).ToList();
}
public ICollection<HrBuildingComponentsV1> BuildingComponents { get; set; }
public static void DefineDbModel(ModelBuilder modelBuilder)
{
modelBuilder.Entity<HrFormSectionV1>(entity =>
{
entity.Property(e => e.Id).ValueGeneratedOnAdd();
});
}
private static readonly Dictionary<Type, Func<HrBuildingComponentV1DTO,HrBuildingComponentsV1>> #switch = new Dictionary<Type, Func<HrBuildingComponentV1DTO,HrBuildingComponentsV1>> {
{ typeof(HrTextBuildingComponentV1DTO), b => new HrTextBuildingComponentV1((HrTextBuildingComponentV1DTO)b) },
};
}
{
public class HrBuildingComponentsV1
{
public HrBuildingComponentsV1() { }
public HrBuildingComponentsV1(HrBuildingComponentV1DTO buildingComponent)
{
Id = buildingComponent.Id;
Label = buildingComponent.Label;
Type = buildingComponent.Type;
Index = buildingComponent.Index;
IsFilter = buildingComponent.IsFilter;
SectionId = buildingComponent.SectionId;
}
public string Id { get; set; }
public string Label { get; set; }
public BuildingComponentType Type { get; set; }
public int? Index { get; set; }
public bool IsFilter { get; set; }
public string SectionId { get; set; }
public HrFormSectionV1 Section { get; set; }
}
public enum BuildingComponentType
{
...
}
}
public class HrTextBuildingComponentV1 : HrBuildingComponentsV1
{
public string Value { get; set; }
public HrTextBuildingComponentV1() : base() { }
public HrTextBuildingComponentV1(HrTextBuildingComponentV1DTO buildingComponentdto)
: base(buildingComponentdto) {
Value = buildingComponentdto.Value;
}
}
So now I have following tables
HrFormV1
HrFormSectionV1
HrBuildingComponentsV1 (TPH) here
I am using Asp.Net core JSON patch to update the records. Add and replace works fine but when I do remove then I get an error
I am removing using this json
{
"op": "remove",
"path": "/formsections/0/buildingcomponents/0"
}
Here I get an error that SectionId cannot be NULL. Can someone guide me here?

How to put values in a list type field

I have 2 classes and VMs. I made a method that displays typegenres, and a list of genres that are related to them, but now I need a list of TypeGenreNamesVM. I don't understand how to pass in GenreNames a list of values Name and NameUrl. I need to make a method that displays data in a similar structure:
[
{
"name": "qwerty",
"nameEng": "qwertyEng",
"GenresNames": [
{
"name": "genre1",
"nameEng": "genreEng1"
},
{
"name": "genre2",
"nameEng": "genreEng2"
}
]
}
]
Here is I have 2 classes and VMs that I using
public class Genre
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string NameForUrl { get; set; }
public string Description { get; set; }
public int Fk_TypeGenreId { get; set; }
[ForeignKey("Fk_TypeGenreId")]
public TypeGenre TypeGenre { get; set; }
public List<Book_Genre> Book_Genre { get; set; }
}
public class TypeGenre
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string NameForUrl { get; set; }
public string Description { get; set; }
public List<Genre> Genre { get; set; }
}
public class TypeGenreTestVM
{
public string Name { get; set; }
public string NameEng { get; set; }
public List<TypeGenreNamesVM> GenreNames { get; set; }
}
public class TypeGenreNamesVM
{
public string Name { get; set; }
public string NameForUrl { get; set; }
}
public async Task<IEnumerable<TypeGenreTestVM>> GetTypesAndGenresEng()
{
var result = await _context.TypeGenre.Select(genres => new TypeGenreTestVM()
{
Name = genres.Name,
NameEng = genres.NameForUrl,
GenreNames =
}).ToListAsync();
return result;
}
Almost the same as the first Select
public async Task<IEnumerable<TypeGenreTestVM>> GetTypesAndGenresEng()
{
var result = await _context.TypeGenre.Select(genres => new TypeGenreTestVM()
{
Name = genres.Name,
NameEng = genres.NameForUrl,
GenreNames = genres.Genre.Select(g => new TypeGenreNamesVM
{
Name = g.Name,
NameEng = g.NameForUrl
})
.ToList()
}).ToListAsync();
return result;
}

Expression of type 'System.Linq.IOrderedQueryable`1[Models.Option]' cannot be used for return type 'System.Linq.IOrderedEnumerable`1[Models.Option]

In the following Query, I want to Sort the Children List of a Parent based on Index Property, which I encounter with the following error ...
How to Fix it ?
Expression of type 'System.Linq.IOrderedQueryable`1[Models.Option]' cannot be used for return type 'System.Linq.IOrderedEnumerable`1[Models.Option]'
Code :
[HttpGet("name={name}&includeSettings={includeSettings}&includeFields={includeFields}")]
public async System.Threading.Tasks.Task<ActionResult<Models.Form>> GetFormByName(string name, bool includeSettings = false, bool includeFields = false)
{
var varForm = _context.Forms
.Where(current => current.Name.Contains(name))
.AsQueryable();
if (includeSettings == true)
{
varForm = varForm
.Include(current => current.FormUiSetting)
.Include(current => current.FormResultSetting);
}
if (includeFields == true)
{
varForm = varForm
.Include(current => current.FieldItems)
.ThenInclude(field => field.Validations)
.Include(current => current.FieldItems)
.ThenInclude(field => field.Options.OrderBy(option => option.Index));
}
return await varForm.SingleOrDefaultAsync();
}
My Model is Like This :
Some FieldItems have Options List and Some not have it...
public class Form
{
public int Id { get; set; }
public string Name { get; set; }
--- some props ---
public List<FieldItem> FieldItems { get; set; }
}
public class FieldItem
{
public int Id { get; set; }
public string FieldItemName { get; set; }
public List<Validation> Validations { get; set; }
}
public class OptionableFieldItem : FieldItem
{
public List<Options> Options { get; set; }
}
public class Validation
{
public int Id { get; set; }
--- some props ---
}
public class Options
{
public int Id { get; set; }
public string Index { get; set; }
}
Change like below:
public async Task<ActionResult<Form>> GetFormByName(string name, bool includeSettings = false, bool includeFields = false)
{
var varForm = _context.Forms
.Where(current => current.Name.Contains(name))
.AsQueryable();
if (includeSettings == true)
{
varForm = varForm
.Include(current => current.FormUiSetting)
.Include(current => current.FormResultSetting);
}
if (includeFields == true)
{
varForm = varForm
.Include(current => current.FieldItems)
.ThenInclude(field => field.Validations)
.Include(current => current.FieldItems)
.ThenInclude(field => field.Options);
varForm.FirstOrDefaultAsync().Result.FieldItems.Options = varForm.FirstOrDefaultAsync()
.Result.FieldItems.Options
.OrderBy(o => o.Index).ToList();
}
return await varForm.SingleOrDefaultAsync();
}
My model:
public class Form
{
public int Id { get; set; }
public string Name { get; set; }
public FormUiSetting FormUiSetting { get; set; }
public FormResultSetting FormResultSetting { get; set; }
public FieldItem FieldItems { get; set; }
}
public class FormUiSetting
{
public int Id { get; set; }
public string FormUiName { get; set; }
}
public class FormResultSetting
{
public int Id { get; set; }
public string FormResultName { get; set; }
}
public class FieldItem
{
public int Id { get; set; }
public string FieldItemName { get; set; }
public Validation Validations { get; set; }
public List<Options> Options { get; set; }
}
public class Validation
{
public int Id { get; set; }
public string ValidateName { get; set; }
}
public class Options
{
public int Id { get; set; }
public string Index { get; set; }
}
UPDATE:
For your requirement,it seems no need to use FieldItem,just use OptionableFieldItem.
Model:
public class Form
{
public int Id { get; set; }
public string Name { get; set; }
public List<OptionableFieldItem> OptionableFieldItems { get; set; }
}
public class FieldItem
{
public int Id { get; set; }
public string FieldItemName { get; set; }
public List<Validation> Validations { get; set; }
}
public class OptionableFieldItem : FieldItem
{
public List<Options> Options { get; set; }
}
public class Validation
{
public int Id { get; set; }
public string ValidateName { get; set; }
}
public class Options
{
public int Id { get; set; }
public string Index { get; set; }
}
Actions:
if (includeFields == true)
{
varForm = varForm.Include(current => current.OptionableFieldItems)
.ThenInclude(field => field.Validations)
.Include(current => current.OptionableFieldItems)
.ThenInclude(field => field.Options);
var data = varForm.FirstOrDefaultAsync().Result.OptionableFieldItems;
foreach (var item in data)
{
item.Options = item.Options.OrderBy(o => o.Index).ToList();
}
}

Map DTO to Entity

These are my Entities: In this scenario, each user can make a Post. Each post can have a list of Items and each item can have a list of users that Tagged in it.
public class Post
{
public int Id { get; set; }
public int UserId { get; set; }
public string Body { get; set; }
public int LikeCount { get; set; }
public PostStatuses Status { get; set; }
[ForeignKey("UserId")]
public User User { get; set; }
public List<PostItem> PostItems { get; set; }
public Post()
{
PostItems = new List<PostItem>();
}
}
public class PostItem
{
public int Id { get; set; }
public int PostId { get; set; }
public long AttachmentId { get; set; } // Refer to CDN file Id
[ForeignKey("PostId")]
public Post Post { get; set; }
public List<PostItemTag> TaggedUsers { get; set; }
}
public class PostItemTag
{
public int PostItemId { get; set; }
public int TaggedUserId { get; set; }
public int X { get; set; }
public int Y { get; set; }
[ForeignKey("PostItemId")]
public PostItem PostItem { get; set; }
[ForeignKey("TaggedUserId")]
public User User { get; set; }
}
These are my DTOs:
public class CreatePostRequestDTO
{
public int UserId { get; set; }
public string Body { get; set; }
public List<PostItemDTO> PostItems { get; set; }
}
public class PostItemDTO
{
public long AttachmentId { get; set; }
public List<PostItemTagDTO> TaggedUsers { get; set; }
}
public class PostItemTagDTO
{
public int UserId { get; set; }
public int X { get; set; }
public int Y { get; set; }
}
And this is my API:
public async Task<BaseResponseDTO<bool>> CreatePost(CreatePostRequestDTO createPostRequestDTO)
{
Post post = new Post()
{
Body = createPostRequestDTO.Body,
Status = PostStatuses.Posted,
UserId = createPostRequestDTO.UserId,
};
post.Mentions = createPostRequestDTO.Mentions.Select(x => new PostMention()
{
Post = post,
UserId = x,
}).ToList();
post.PostItems = createPostRequestDTO.PostItems.Select(x => new PostItem()
{
AttachmentId = x.AttachmentId,
Post = post,
PostAttachmentType = x.PostAttachmentType,
TaggedUseres = x.TaggedUseres.Select(c => new PostItemTag()
{
UserId = c.UserId,
X = c.X,
Y = c.Y,
PostItemId = ? // My problem is here.
}).ToList(),
}).ToList();
...
}
How can I solve it?
Edit:
Some extra code removed.
Edit2:
And also some extra descriptions removed.
For model binding with Automapper, follow steps below:
Install package AutoMapper and AutoMapper.Extensions.Microsoft.DependencyInjection
Add services.AddAutoMapper(typeof(Startup)); to Startup.cs
Add ModelProfile.cs like
public class ModelProfile: Profile
{
public ModelProfile()
{
CreateMap<CreatePostRequestDTO, Post>();
CreateMap<PostItemDTO, PostItem>();
CreateMap<PostItemTagDTO, PostItemTag>();
}
}
UseCase
public class HomeController : Controller
{
private readonly IMapper _mapper;
private readonly ApplicationDbContext _context;
public HomeController(IMapper mapper
, ApplicationDbContext context)
{
_mapper = mapper;
_context = context;
}
public async Task<IActionResult> Index()
{
CreatePostRequestDTO createPostRequestDTO = new CreatePostRequestDTO {
Body = "B1",
UserId = 1,
PostItems = new List<PostItemDTO> {
new PostItemDTO { AttachmentId = 1, TaggedUsers = new List<PostItemTagDTO>{
new PostItemTagDTO{ UserId = 1, X = 1, Y= 11 }
} }
}
};
var post = _mapper.Map<Post>(createPostRequestDTO);
await _context.AddAsync(post);
await _context.SaveChangesAsync();
return View();
}
}

C# EF List from two classes

I have two classes:
public partial class Alergy
{
public int ID { get; set; }
public Nullable<int> VaccinationAlergyID { get; set; }
public string PHN { get; set; }
public virtual VaccinationAlergy VaccinationAlergy { get; set; }
}
public partial class VaccinationAlergy
{
public VaccinationAlergy()
{
this.Alergies = new HashSet<Alergy>();
}
public int VaccinationAlergyID { get; set; }
public string VaccinationAlergyName { get; set; }
public virtual ICollection<Alergy> Alergies { get; set; }
}
I am using the following to get two values from these models using:
var vaccination = db.Alergies.Where(x => x.PHN == phn)
.Select(x => new { VaccinationAlergyID= x.VaccinationAlergyID,
VaccinationAlergyName= x.VaccinationAlergy.VaccinationAlergyName}).ToList();
I get only the first VaccinationAlergyName the rest are the id of VaccinationAlergyName.
Would appreciate your suggestions.
Try
var vaccination = db.Alergies.Where(x => x.PHN == phn).Include(x=> x.VaccinationAlergy).Select(x => new { VaccinationAlergyID= x.VaccinationAlergyID,VaccinationAlergyName=x.VaccinationAlergy.VaccinationAlergyName}).ToList();

Categories

Resources