Answered by:
[EF Core] Find an entity with a string field ?

Question
-
User-1370514677 posted
Hi everyone,
Is there a way to find an entity with a string field instead of its Id ? Or at least find an enity's Id from one of its fields ?
Indeed I'd like to achieve the following :
[HttpGet] public async Task<IActionResult> GetArticleCategoryImage(int Id) { var current_article = await _articleContext.Article.FindAsync(Id); // var category_id = find id with this key : current_article.CategoryName (string) var article_category = await _articleContext.Category.FindAsync(current_article.CategoryName); var ImageFile = article_category.Image; return File(ImageFile,"image/svg+xml"); }
Article.cs
using System.ComponentModel.DataAnnotations; namespace DevAstuces.Models { public class Article { [Key] public int Id { get; set; } public virtual ApplicationUser Author { get; set; } [Required(ErrorMessage = "Merci de spécifier une catégorie")] public string CategoryName { get; set; } [Required(ErrorMessage = "Merci de spécifier un titre")] [Display(Name="Title", Prompt="Titre")] public string Title { get; set; } [Required(ErrorMessage = "Merci de spécifier une description")] [Display(Name="Description", Prompt="Description")] public string Description { get; set; } [Required(ErrorMessage = "Merci de saisir un article")] [Display(Name="Content", Prompt="Saisissez votre article")] public string Content { get; set; } public enum ArticleStatus { Pending, Rejected, Validated } public ArticleStatus Status { get; set; } } }
Category.cs
using System.ComponentModel.DataAnnotations; namespace DevAstuces.Models { public class Category { [Key] public int Id { get; set; } public byte[] Image { get; set; } [Required] public string Name { get; set; } } }
A Category is linked to an Article via this form :
<form id="editor_pane" method="POST"> <input list="Category" asp-for="@Model.Article.CategoryName"> <datalist id="Category"> @foreach(var category in Model.CategoryList) { <option value="@category.Name"></option> } </datalist> // Code omitted for clarity <div id="editor_controls"> <button type="button" onclick="previewArticle()">Prévisualiser</button> <input value="Valider" type="submit"> </div> </form>
Tuesday, February 23, 2021 2:34 PM
Answers
-
User475983607 posted
Learn LINQ fundamentals.
https://docs.microsoft.com/en-us/ef/core/querying/
var val = await _articleContext.Article.Where(m => m.CategoryName == "TheValueYouAreLookingFor").ToListAsync();
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, February 23, 2021 3:59 PM
All replies
-
User475983607 posted
Learn LINQ fundamentals.
https://docs.microsoft.com/en-us/ef/core/querying/
var val = await _articleContext.Article.Where(m => m.CategoryName == "TheValueYouAreLookingFor").ToListAsync();
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, February 23, 2021 3:59 PM -
User1120430333 posted
Find and FindAsync only finds an entity by its primary key ID.
DbContext.Find Method (Microsoft.EntityFrameworkCore) | Microsoft Docs
DbContext.FindAsync Method (Microsoft.EntityFrameworkCore) | Microsoft Docs
Tuesday, February 23, 2021 4:01 PM -
User-1370514677 posted
Hi @mgebhard,
Thank you for your answer.
I changed my code accordingly in my ArticleController.cs :
[HttpGet] public async Task<IActionResult> GetArticleCategoryImage(int Id) { // Get current article through Id passed as an argument var current_article = await _articleContext.Article.FindAsync(Id); // Find which Category is linked to the current_article by retrieving the Category's Id through the current_article.CategoryName matching with Category.Name var category = await _articleContext.Category.SingleAsync(m => m.Name == current_article.CategoryName); // Get Category Image var ImageFile = category.Image; return File(ImageFile,"image/svg+xml"); }
Yet, I don't get the SVG image that is wanted in my CSHTML code (just a blank square with nothing) :
@foreach(var article in Model.ArticleList) { <a asp-controller="Article" asp-action="GetArticle" asp-route-id="@article.Id"> <div class="article article_a"> <object data="/Article/GetArticleCategoryImage/@article.Id" type="image/svg+xml" class="article_category"></object> <div class="article_content"> <p class="article_header">@article.Title</p> <div class="article_description"> @article.Description </div> </div> </div> </a> }
Tuesday, February 23, 2021 5:01 PM -
User475983607 posted
There are too many potential problems with your code. Learn how to troubleshoot code and use debugging tools.
https://docs.microsoft.com/en-us/visualstudio/debugger/debugger-feature-tour?view=vs-2019
I would do paste a valid controller/action URL in the browser's address bar to see if an SVG image is returned. If you see the expected image then there is a problem elsewhere in the code. If you do not see the expected image, open the browser's dev tools and look for errors in the network view. Read the error go form there.
Also set a break point in the action and view each of the variables to make sure they contain expected values.
Tuesday, February 23, 2021 7:48 PM -
User-1370514677 posted
Hi @mgebhard,
I debugged my code with your advices (I've directly copy/paste the URL in the browser) and found that the var category is actually null :
[HttpGet] public async Task<IActionResult> GetArticleCategoryImage(int Id) { // Get current article through Id passed as an argument var current_article = await _articleContext.Article.FindAsync(Id); // Find which Category is linked to the current_article by retrieving the Category's Id through the current_article.CategoryName matching with Category.Name var category = await _articleContext.Category.SingleOrDefaultAsync(m => m.Name == current_article.CategoryName); if(category == null) System.Console.WriteLine("Category is NULL"); // Get Category Image var ImageFile = category.Image; return File(ImageFile,"image/svg+xml"); }
So it seems that my LINQ query is not finding the requested category with the CategoryName I passed it.
For example :
- User creates an Article about csharp and select "csharp" as a Category object (present in the DB)
- The Article.CategoryName = "csharp"
- But the LINQ query above won't find the "csharp" Cateogry object through the string "csharp"
Wednesday, February 24, 2021 8:47 AM -
User475983607 posted
But the LINQ query above won't find the "csharp" Cateogry object through the string "csharp"Continue troubleshooting and debugging. The next step is solving why the LINQ query returns a null category.
Open the Category table and verify the table contains "csharp" in the Name column. Use the SQL Server Object Explorer in Visual Studio or SSMS to view the table contents.
IMHO, the design has bugs. The Article should contain the category Id not the CategoryName. See the following reference documentation which explains how to create a one to many relationship using Code First in EF Core.
Wednesday, February 24, 2021 12:42 PM -
User-1370514677 posted
EDIT : it's actually working but I forgot to recreate the categories as I deleted the DB and my browser had the former names in cache..
Thank you anyways guys ;)
Wednesday, February 24, 2021 2:59 PM