1

我正在我的派生类中尝试newICollections - 这应该在对象构造函数中完成还是/以及当我在我的Register ActionResult()?

租户继承自 UserProfile - 简化示例:

public class Tenant : UserProfile
{
    public Tenant() 
    {
        this.ReferencePhotos = new List<ReferencePhoto>();
        // ReferencePhoto extends Image
    }

    // A Tenant can have many ReferencePhotos
    [ForeignKey("ImageId")] // Id of parent class
    public virtual ICollection<ReferencePhoto> ReferencePhotos { get; set; }
}

我尝试执行上述操作,但会导致 InvalidCastException:

无法将 'System.Collections.Generic.List'1[Namespace.Models.ReferencePhoto]' 类型的对象转换为类型 [Namespace.Models.ReferencePhoto]'。

当它们相同时,为什么要尝试从一个对象投射到另一个对象?

在我的Register ActionResult()我也试过这个(在对象构造函数中设置和不设置 ICollections):

public ActionResult Register(RegisterModel model)
{
    using (var db = new LetLordContext())
    {
        var tenant = db.UserProfile.Create<Tenant>();
        tenant.ReferencePhotos = new List<ReferencePhoto>();
        // Do I need to new it here at all/as well?
        db.UserProfile.Add(tenant);     // Exception being thrown here
        db.SaveChanges();

        Roles.AddUserToRole(model.UserName, "Tenant");

        WebSecurity.Login(model.UserName, model.Password);
        return RedirectToAction("Confirm", "Home", tenant);
     } 
}

上面也抛出了前面提到的相同异常。任何人都可以提供任何见解吗?

编辑:添加了用户配置文件代码

public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.None)]
    public int UserId { get; set; }

    [Display(Name = "Username")]
    [Required(ErrorMessage="Username is required.")]
    public string UserName { get; set; }

    [Display(Name = "First name")]
    [Required(ErrorMessage = "First name is required.")]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "Account type is required.")]
    public AccountType AccountType;

    public virtual string AccountTypeString
    {
        get { return AccountType.ToString(); }
        set
        {
            AccountType newValue;
            if (Enum.TryParse(value, out newValue))
            { AccountType = newValue; }
        }
    }
}

编辑:添加上下文代码和 ReferencePhoto 代码

public class LetLordContext : DbContext
{
    public DbSet<LetLord.Models.UserProfile> UserProfile { get; set; }                  // 1 DbSet for superclass UserProfile
    public DbSet<LetLord.Models.Image> Image { get; set; }                              // 1 DbSet for superclass Image
    public DbSet<LetLord.Models.ResidentialProperty> ResidentialProperty { get; set; }
    public DbSet<LetLord.Models.TenantGroupMember> TenantGroupMember { get; set; }
    public DbSet<LetLord.Models.Viewing> Viewing { get; set; }
    public DbSet<LetLord.Models.TenantPreferences> TenantPreferences { get; set; }
    public DbSet<LetLord.Models.LandlordPreferences> LandlordPreferences { get; set; }
    public DbSet<LetLord.Models.Address> Address { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}

我正在使用 table-per-type 继承,因此只DbSet实现了基类的 s 。

public class ReferencePhoto : Image
{
    // 1:many with Tenant
    public int UserId { get; set; }
    [ForeignKey("UserId")]
    public virtual Tenant Tenant { get; set; }
}

我可以通过不在对象构造函数中初始化列表或在创建新实体时解决此问题。为了实现这一点,我在 GET 中使用了一个 null 合并运算符,它在部分视图ActionResult中返回一个Tenant对象。在部分中,我检查是否Model.ReferencePhotos == null. 如果是,用户可以上传照片。上传照片后,它被添加到列表中,我可以通过检查数据库来确认这一点。但是,当我再次登录时,if前面提到的局部视图中的 抛出以下异常:

无法在 System.Data.Entity.DynamicProxies.Tenant_ 类型上设置字段/属性 ReferencePhotos...

有一个内部例外:

无法将“System.Data.Entity.DynamicProxies.ReferencePhoto_3DFB9F64061D55E5AF6718A74C97025F77EFB2BB9C2A6E43F5A6AF62A6A73E75”类型的对象转换为“System.Collections.Generic.ICollection`1[LetLord.Models.ReferencePhoto]”类型的对象。”}

这可能会提供更多的洞察力。

4

1 回答 1

1

尝试删除...

[ForeignKey("ImageId")] // Id of parent class

ForeignKey 应该设置在“一个”端(一对多),从不设置在集合上——它只定义在( 你已经ReferencePhoto通过它归因)。UserId

...这也可能是添加额外的外键- 并导致该single instance vs collection错误。



有关如何ForeignKey定义的更多信息(ForeignKey vs InverseProperty等),以及大师的一些好建议:)

实体框架 4.1 InverseProperty 属性

我应该如何在 MVC3 中使用 Code First Entity Framework (4.1) 声明外键关系?


对于更复杂的场景(在流畅的代码中使用多对多和手动定义关系 - 我推荐) - 看看我前段时间制作的这些详细示例 - 它具有您可能需要的大部分映射。

使用codefirst或fluent API与同一实体的多对多(连接表)关系?

联接表中的 Code First Fluent API 和导航属性

带有附加数据的 EF 代码优先多对多

于 2013-03-25T15:28:05.890 回答