سری بررسی SQL Smell در EF Core - ایجاد روابط Polymorphic - بخش دوم
نویسنده: سیروان عفیفی
تاریخ: ۱۳۹۹/۰۵/۰۹ ۱۳:۱۰
آدرس: www.dntips.ir
| مطالب | ۳۶۹۴ |
| نویسندگان | ۲۷۶ |
| گروههای مطالب | ۱۰۲۴ |
| نقشههای راه | ۱۱۹ |
| دورهها | ۱۴ |
| اشتراکها | ۱۷۹۱۴ |
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
/**
* Get the owning commentable model.
*/
public function commentable()
{
return $this->morphTo();
}
}
class Post extends Model
{
/**
* Get all of the post's comments.
*/
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
}
class Video extends Model
{
/**
* Get all of the video's comments.
*/
public function comments()
{
return $this->morphMany('App\Comment', 'commentable');
}
} $post = App\Post::find(1);
foreach ($post->comments as $comment) {
//
} $comment = App\Comment::find(1); $commentable = $comment->commentable;
public enum CommentType
{
Article,
Video,
Event
}
public class Comment
{
public int Id { get; set; }
public string CommentText { get; set; }
public string User { get; set; }
public int? TypeId { get; set; }
public CommentType CommentType { get; set; }
} public class Comment
{
public int Id { get; set; }
public string CommentText { get; set; }
public string User { get; set; }
public virtual Article Article { get; set; }
public int ArticleId { get; set; }
}
public class Article
{
public int Id { get; set; }
public string Title { get; set; }
public string Slug { get; set; }
public string Description { get; set; }
public virtual ICollection<Article> Articles { get; set; }
} interface ICommentable
{
int Id { get; set; }
}
public class Article : ICommentable
{
public int Id { get; set; }
public string Title { get; set; }
public string Slug { get; set; }
public string Description { get; set; }
[NotMapped]
public ICollection<Comment> Comments { get; set; }
}
public class Video : ICommentable
{
public int Id { get; set; }
public string Url { get; set; }
public string Description { get; set; }
[NotMapped]
public ICollection<Comment> Comments { get; set; }
}
public class Event : ICommentable
{
public int Id { get; set; }
public string Name { get; set; }
public DateTimeOffset? Start { get; set; }
public DateTimeOffset? End { get; set; }
[NotMapped]
public ICollection<Comment> Comments { get; set; }
} public class Comment
{
public int Id { get; set; }
public string CommentText { get; set; }
public string User { get; set; }
public int? TypeId { get; set; }
public CommentType CommentType { get; set; }
ICommentable _parent;
[NotMapped]
public ICommentable Parent
{
get => _parent;
set
{
_parent = value;
TypeId = value.Id;
CommentType = (CommentType) Enum.Parse(typeof(CommentType), value.GetType().Name);
}
}
} var article = dbContext.Articles.Find(1);
article.Comments = dbContext.Comments
.Where(c => c.TypeId == article.Id
&& c.CommentType == CommentType.Article)
.ToList();
foreach (var comment in article.Comments)
comment.Parent = article;
foreach (var comment in article.Comments)
{
Console.WriteLine($"{comment.User} - ${comment.CommentText} - {((Article) comment.Parent).Title}");
} CREATE TRIGGER delete_article_comments
AFTER DELETE ON Articles
FOR EACH ROW
BEGIN
DELETE FROM Comments WHERE CommentType = 'Article' AND TypeID = OLD.Id;
END;