Reputation: 131
In frontend in Angular I created the possibility of adding tags and memes. In the back-end in the web api I would like to save the tags in the database. Using entity framework code first, I created the structure of three tables:
public class Memes
{
public int Id { get; set; }
public string MemName { get; set; }
public string UserId { get; set; }
public string Image { get; set; }
public List<Memes_tags> MemesIteam { get; set; }
}
public class HashTag
{
public int Id { get; set; }
public int MemesId { get; set; }
public string Name { get; set; }
}
public class Memes_tags
{
public int Id { get; set; }
public int MemesId { get; set; }
public int HashTagId { get; set; }
public virtual Memes Memes { get; set; }
public virtual HashTag HashTags { get; set; }
}
Then I created a method that should save memes and tags in the database:
[HttpPost]
[Route("api/Memes/AddMemes")]
public IHttpActionResult CreateMemes([FromBody] MemHashTagsViewModel createMem)
{
ApplicationDbContext db = new ApplicationDbContext();
if (createMem != null)
{
Memes mem = new Memes()
{
MemName = createMem.MemName,
Image = createMem.Image,
UserId = createMem.UserId
};
db.MemesModel.Add(mem);
foreach (var item in createMem.HashTags)
{
var hashTag = new HashTag()
{
MemesId = mem.Id,
Name = item
};
db.HashTags.Add(hashTag);
}
db.SaveChanges();
return Ok();
}
else
{
return NotFound();
}
}
Incoming data:
I have problem with the correct Memes Id record. For example, I created a mem that has Id = 4 and in the table HashTags should be 4 and in my case is 0.
Is there any other better solution for saving tags in the database? Is my solution is good?
Upvotes: 0
Views: 1089
Reputation: 3224
Yeah, the thing is: since you didn't save the mem first, it doesn't have an ID when you add it to the hashtag.
If you want to do it that way, you should make HashTag a member, in form of a list (property) on the mem. Then, when creating the HashTag objects, not add a member ID. The merely add the Mem to the database, and EF will take care of the object structure.
(On my phone, will make a code example in the morning if no one beats me to it)
EDIT: Here's how i would do it:
Respectfully: Drop the Memes_tags class as their seems to be no point in having it at all. It merely works as a relation between Memes and HashTags, but that already exists.
For purposes of Best practice, at least according to MS's own EF 'get start' doc the id of the class should be named: <class_name>Id
, so that has been 'corrected' as well.
public class Memes
{
public int MemesId { get; set; }
public string MemName { get; set; }
public string UserId { get; set; }
public string Image { get; set; }
public List<HashTag> HashTags { get; set; }
}
public class HashTag
{
public int HashTagId { get; set; }
public int MemesId { get; set; }
public string Name { get; set; }
public virtual Memes { get; set; }
}
Below is the modified 'CreateMemes'. The idea is, that instead of adding the ID of the 'Memes' to hashtag, we merely add the HashTags to the meme object, thus they are add to EF as well, and when the 'Memes' record is add to the database, EF will make certain to create the hashtags too.
[HttpPost]
[Route("api/Memes/AddMemes")]
public IHttpActionResult CreateMemes([FromBody] MemHashTagsViewModel createMem)
{
ApplicationDbContext db = new ApplicationDbContext();
if (createMem != null)
{
Memes mem = new Memes()
{
MemName = createMem.MemName,
Image = createMem.Image,
UserId = createMem.UserId
};
foreach (var item in createMem.HashTags)
{
var hashTag = new HashTag()
{
Name = item
};
mem.HashTags.add(hashTag);
}
db.add(mem);
db.SaveChanges();
return Ok();
}
else
{
return NotFound();
}
}
Upvotes: 1
Reputation: 77936
Just adding the created instance to the context entity model isn't enough db.MemesModel.Add(mem);
. Id value doesn't gets generated unless you call SaveChanges()
on it. This in your below code there is no Id value yet and so what you observe
var hashTag = new HashTag()
{
MemesId = mem.Id,
Name = item
};
Upvotes: 1