【问题标题】:EF: Wrong relations when calling from partial view?EF:从局部视图调用时的错误关系?
【发布时间】:2013-07-16 11:50:09
【问题描述】:

我正在尝试实现记录查看和点击的自制横幅系统。好吧,几乎一切正常,除了当我打开一个页面并从局部视图调用 RenderBanners() 操作时。它被调用如下:

_Layout.cshtml 通过@Html.Partial("_Header") 调用_Header.cshtml,然后在_Header.cshtml 中我通过@{ Html.RenderAction("RenderBanners", "Home"); } 调用此操作。

渲染横幅操作:

        [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 url,我会得到部分视图,所有内容都正确呈现并将所有内容保存到数据库中。 它也适用于此操作:

[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);

我相信我的模型和关系是正确的,因为它在大多数情况下都有效...除了通过 Partial 视图调用 Action 时?什么鬼?

编辑:这个项目使用存储库模式,我们有一个接口 IRepository 和 Repository 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

【问题讨论】:

  • SaveOrUpdate 方法是如何工作的?
  • 更新了原始问题。 @Vyacheslav Volkov
  • BannerBannerLog 的 ID 在哪里设置?
  • @Bob Banner 从数据库中获取它的 ID(有效的现有编号),BannerLog 的 ID 为 0,如果 ID == 0,则添加它 - EntityFramework(或 SQL,不知道)分配一个新 ID。
  • 哎呀,错过了DatabaseGenerated 部分。您是否尝试过将新的 BannerLog 创建为对象,然后再将其保存为 SaveOrUpdate 以检查 BannerLog 对象是否已正确创建?即分两步创建BannerLog 1) 创建BannerLog 2) SaveOrUpdate BannerLog 对象。

标签: c# asp.net-mvc entity-framework entity-framework-5


【解决方案1】:

由于我仍然不知道到底发生了什么,所以我做了一个快速破解 - 而不是做 @{ Html.RenderAction("RenderBanners", "Home"); } 我只是从 JavaScript 调用这个动作:

<div id="bannerDiv"></div>
<script>
    $("#bannerDiv").load('@Url.Action("RenderBanners", "Home")');
</script>

工作正常...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    • 2023-03-18
    相关资源
    最近更新 更多