我正在尝试实现自制的横幅系统,该系统记录视图和点击。几乎所有东西都可以工作,除非我打开一个页面并且从部分视图调用RenderBanners()动作。它被调用如下:
_Layout.cshtml通过@Html.Partial("_Header")
调用_Header.cshtml,然后在_Header.cshtml中通过@{ Html.RenderAction("RenderBanners", "Home"); }
调用此操作。
RenderBanners动作:
[AllowAnonymous]
public ActionResult RenderBanners()
{
var banners = bannerTimeRepository.ForcefulGetAll().ToList();
try
{
foreach(var banner in banners)
{
bannerLogRepository.SaveOrUpdate(new BannerLog
{
Timestamp = DateTime.Now,
Action = BannerAction.View,
User = membership.LoggedUser,
Banner = banner
});
}
}
catch(Exception ex)
{
var tralala = ex;
}
return View(banners);
我得到了这个InvalidOperationException:
由于一个或多个外键属性不可为空,因此无法更改关系。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。
似乎我的模型不正确,对吧?
好吧,如果我访问 ~/Home/RenderBanners
网址,我会获得部分视图,其中所有内容都正确,所有内容已保存到数据库中。
它也适用于此操作:
[AllowAnonymous]
public ActionResult FollowBanner(int id)
{
var banner = bannerRepository.ForcefulGetById(id);
bannerLogRepository.SaveOrUpdate(new BannerLog
{
Timestamp = DateTime.Now,
Action = BannerAction.Click,
User = membership.LoggedUser,
Banner = banner
});
return Redirect(banner.Href);
}
我的模特:
public abstract class Entity
{
[Key]
public int Id { get; protected set; }
}
public class Banner : Entity
{
//omited
}
public class BannerLog : Entity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public new int Id { get; set; }
public BannerAction Action { get; set; }
public User User { get; set; }
public DateTime Timestamp { get; set; }
public Banner Banner { get; set; }
}
public enum BannerAction
{
View = 0,
Click = 1
}
模型构建器:
modelBuilder.Entity<BannerLog>().HasRequired(x => x.Banner).WithMany().WillCascadeOnDelete(true);
modelBuilder.Entity<BannerLog>().HasOptional(x => x.User).WithMany().WillCascadeOnDelete(false);
我相信我的模型和关系是正确的,因为它大部分时间都有效...除非通过部分视图调用Action?怎么了?
编辑:这个项目使用了存储库模式,我们有一个接口IRepository&lt; T&gt;和存储库&lt; T&gt; SaveOrUpdate的实现是: public virtual T SaveOrUpdate(T entity)
{
var casted = entity as Entity;
if(casted.Id == 0)
this.Context.Set<T>().Add(entity);
this.Context.SaveChanges();
return entity;
}
bannerLogRepository只是Repository&lt; BannerLog&gt;。
答案 0 :(得分:0)
因为我仍然不知道到底是怎么回事,所以我快速入侵了 - 而不是做@{ Html.RenderAction("RenderBanners", "Home"); }
我只是从JavaScript中调用此Action:
<div id="bannerDiv"></div>
<script>
$("#bannerDiv").load('@Url.Action("RenderBanners", "Home")');
</script>
工作得很好......