I have 2 entities named News
and NewsAttachment
in the .Core Project. These entities have a relationship through News_Id
. In other words, when I create new News
and add it into database, this News
may have one or two attachment media that I want to insert in the related table named NewsAttachment
. So I may want to retrieve News_Id
and insert attachments in the related table.
I define 2 DTOs named NewsDto
and CreateNewsDto
in NewsAppService
and I pass CreateNewsDto
to insert new News
, but I have no idea how to do it for NewsAttachment
.
Here is my News
entity:
public class News : FullAuditedEntity<long>
{
public const int MaxTitleLength = 150;
public const int MaxContentLength = 1200;
public const int MaxMetaTagLength = 60;
[Required]
[MaxLength(MaxTitleLength)]
public string Title { get; set; }
[Required]
public string Code { get; set; }
[Required]
[MaxLength(MaxContentLength)]
public string Content { get; set; }
public DateTime PublishDate { get; set; }
[MaxLength(MaxMetaTagLength)]
public string Tags { get; set; }
public virtual NewsType Type { get; set; }
public virtual ICollection<NewsAttachment> Attachments { get; set; }
}
and NewsAttachment
entity:
public class NewsAttachment: FullAuditedEntity<long>
{
public const int MaxTitleLength = 50;
[Required]
[MaxLength(MaxTitleLength)]
public string FileName { get; set; }
[Required]
public byte[] File { get; set; }
public string FileExtension { get; set; }
public int FileSize { get; set; }
[Required]
public DateTime RegisterDate { get; set; }
public virtual News News { get; set; }
}
and the DTOs:
public class NewsDto : EntityDto<long>
{
public const int MaxTitleLength = 50;
public const int MaxContentLength = 800;
public const int MaxMetaTagLength = 60;
[Required]
[MaxLength(MaxTitleLength)]
public string Title { get; set; }
[Required]
public string Code { get; set; }
[Required]
[MaxLength(MaxContentLength)]
public string Content { get; set; }
public DateTime PublishDate { get; set; }
[MaxLength(MaxMetaTagLength)]
public string Tags { get; set; }
public virtual NewsType Type { get; set; }
}
and:
public class CreateNewsDto
{
public const int MaxTitleLength = 50;
public const int MaxContentLength = 800;
public const int MaxMetaTagLength = 60;
[Required]
[MaxLength(MaxTitleLength)]
public string Title { get; set; }
[Required]
public string Code { get; set; }
[Required]
[MaxLength(MaxContentLength)]
public string Content { get; set; }
public DateTime PublishDate { get; set; }
[MaxLength(MaxMetaTagLength)]
public string Tags { get; set; }
public virtual NewsType Type { get; set; }
public virtual ICollection<NewsAttachment> Attachments { get; set; }
}
Here is my presumptive method in NewsAppService
to insert new News
and add related media to NewsAttachment
table:
public virtual NewsDto InsertWithMedia(CreateNewsDto input, NewsAttachmentDto attach)
{
var news = ObjectMapper.Map<NewsManagement.News>(input);
var newsAttachment = ObjectMapper.Map<NewsAttachment>(attach);
newsAttachment.News.Id = news.Id;
return MapToEntityDto(news);
}
Two choices:
ICollection
and let EF handle the entities:public virtual NewsDto InsertWithMedia(CreateNewsDto input, NewsAttachmentDto attach)
{
var news = ObjectMapper.Map<NewsManagement.News>(input);
news.Attachments = new List<NewsAttachment>(); // 1
var newsAttachment = ObjectMapper.Map<NewsAttachment>(attach);
news.Attachments.Add(newsAttachment); // 2
_newsRepository.Insert(news); // 3
CurrentUnitOfWork.SaveChanges(); // 4
return MapToEntityDto(news);
}
Id
instead of collection, with a foreign key:public class NewsAttachment: FullAuditedEntity<long>
{
// ...
public virtual long NewsId { get; set; }
public virtual News News { get; set; }
}
public virtual NewsDto InsertWithMedia(CreateNewsDto input, NewsAttachmentDto attach)
{
var news = ObjectMapper.Map<NewsManagement.News>(input);
var newsId = _newsRepository.InsertAndGetId(news); // 1
var newsAttachment = ObjectMapper.Map<NewsAttachment>(attach);
newsAttachment.NewsId = newsId; // 2
_newsAttachmentRepository.Insert(newsAttachment); // 3
CurrentUnitOfWork.SaveChanges(); // 4
return MapToEntityDto(news);
}
The second is good for updating — when newsId
is already known — but may require additional steps if NewsDto
also has Attachments
(which should be ICollection<AttachmentDto>
type).