我是'实体框架'和'代码优先'世界的新手,所以请耐心等待。我有2个实体文章和标签。标签中的 TagName 列必须是唯一的,因为它是密钥。在后续文章中使用现有标记时,我遇到了主键冲突问题。我的实体看起来如下
public class Article
{
public Article()
{
}
public int Id { get; set; }
[StringLength(100)]
[Required]
public string Title { get; set; }
[Required]
public string Body { get; set; }
public virtual List<Tag> Tags { get; set; }
}
和
public class Tag
{
public Tag()
{
}
public Tag(string tagName)
{
TagName = tagName;
}
[Key]
[StringLength(25)]
public string TagName { get; set; }
public virtual List<Article> Articles { get; set; }
public override string ToString()
{
return this.TagName;
}
}
EF为文章,标签和TagArticles关系创建3个表
这是保存文章的代码
var editedTags = Request["Tags"];
if (!string.IsNullOrEmpty(editedTags))
{
var tags = Regex.Split(editedTags, "\r\n");
if (tags != null && tags.Length > 0)
{
foreach (var tag in tags)
{
article.Tags.Add(new Tag(tag));
}
}
}
//db is my context
db.Articles.Add(article);
db.SaveChanges(); //Crashes here if the tag already exists
除了手动创建标签之外,有没有办法告诉EF在创建标签之前先检查标签是否存在以避免重复?
答案 0 :(得分:1)
找到解决方案。对于Tag
类,我添加了一个int列 Id 并将其作为主键。然后我更新了数据库以反映更改。这是:
public class Tag
{
public Tag()
{
}
public Tag(string tagName)
{
TagName = tagName;
}
[Key]
public int Id { get; set; }
[Required]
[StringLength(25)]
public string TagName { get; set; }
public virtual List<Article> Articles { get; set; }
public override string ToString()
{
return this.TagName;
}
}
我添加了一个为文章添加新标签的功能
private Article ParseTags(Article article)
{
var strTags = Request["Tags"];
if (!string.IsNullOrEmpty(strTags))
{
var arrTags = Regex.Split(strTags, "\r\n");
if (arrTags != null && arrTags.Length > 0)
{
foreach (var tagName in arrTags)
{
var tag = db.Tags.FirstOrDefault(t => t.TagName.ToLower() == tagName.ToLower());
if (tag == null)
article.Tags.Add(new Tag(tagName));
else
article.Tags.Add(tag);
}
}
}
return article;
}
最后是Create
动作
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include="Title,Body")] Article article)
{
if (ModelState.IsValid)
{
db.Articles.Add(ParseTags(article));
db.SaveChanges();
return RedirectToAction("Index");
}
return View(article);
}
现在只创建新标签,不重复现有标签,并在TagsArticles连接表中正确创建关系。
答案 1 :(得分:0)
替换代码的以下行
foreach (var tag in tags)
{
article.Tags.Add(new Tag(tag));
}
使用
foreach (var tag in tags)
{
Tag objTag = db.Tags.SingleOrDefault(c => c.TagName == tag);
if (!(objTag != null && objTag.TagName == tag))
objTag = new Tag(tag);
article.Tags.Add(objTag);
}