实体框架 - 使用类继承创建模型

时间:2014-04-28 13:25:25

标签: c# entity-framework inheritance model entity-framework-6

尝试使用代码第一实体框架6.1的继承创建模型对象时遇到一些奇怪的问题。

我在共享代码库中创建了一个基本User类,在我的应用程序中,我创建了另一个从基类继承的User类。

基本用户类:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using CSAMLib.Data.Entity;
using CSAMLib.Security.Cryptography;
using System.ComponentModel.DataAnnotations;

namespace CSAMLib.Security
{
    public class User : BaseEntity, CSAMLib.Security.IUser
    {
        public bool Active { get; set; }

        [Display(Name = "First name")]
        public String FirstName { get; set; }

        [Display(Name = "Last name")]
        public String LastName { get; set; }

        [Display(Name = "Full name")]
        public String FullName { get { return (FirstName == null ? String.Empty : FirstName + " ") + (LastName ?? String.Empty); } }

        [Display(Name = "Login", Prompt = "someone@example.com")]
        public String Login { get; set; }

        [Display(Name = "Email address")]
        public String EmailAddress { get; set; }

        public byte[] Password { get; set; }

        [Display(Name = "Last login date")]
        public DateTime? LastLoginDate { get; set; }

        [Display(Name = "Logged in")]
        public bool CurrentlyLoggedIn { get; set; }

        [Display(Name = "Signature filepath")]
        public byte[] SignatureFileContent { get; set; }

        [Display(Name = "Signature filename")]
        public String SignatureFileName { get; set; }

        [Display(Name = "Signature content")]
        public String SignatureContentType { get; set; }

        public String Qualification { get; set; }

        [NotMapped]
        public String NewPassword { get; set; }
        [NotMapped]
        public PasswordPolicy PasswordPolicy { get; set; }

        public virtual ICollection<UserRole> UserRoles
        {
            get;
            set;
        }

        public byte[] Salt { get; set; }

    }
}

用户类:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;

namespace Muro.Models
{
    [Table("Users")]
    public class User : CSAMLib.Security.User
    {
        public bool ClientUser { get; set; }

        [Display(Name = "Company")]
        [ForeignKey("Company")]
        public Int64? CompanyID { get; set; }
        public virtual Company Company { get; set; }

        public new ICollection<UserRole> UserRoles
        {
            get;
            set;
        }


        public SystemUser CreateNewUser(string userName, string emailAddress, string firstName, string lastName)
        {
            var user = new Muro.Models.User();
            user.Login = userName;
            user.EmailAddress = emailAddress;
            user.Active = false;
            user.CurrentlyLoggedIn = false;
            user.FirstName = firstName;
            user.LastName = lastName;
            return user;
        }
    }

的DbContext:

public DbSet<Muro.Models.User> Users { get; set; }

此方法在运行update-database时导致以下错误:

  

类型&#39; CSAMLib.Security.User&#39;和类型   &#39; Muro.Models.User&#39;两者都有相同的简单名称   &#39;用户&#39;所以不能在同一型号中使用。给定的所有类型   model必须具有唯一的简单名称。使用&#39; NotMappedAttribute&#39;或者打电话   忽略Code First流畅的API以明确排除属性   或从模型中输入。

我可以理解这一点,因为两个类名共享简单的名称。我的下一个方法是将应用程序User类重命名为SystemUser以解决此问题。但是,我现在收到以下错误,并且不太确定下一步该怎么做。

错误:

System.InvalidOperationException: Sequence contains more than one element
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at System.Data.Entity.ModelConfiguration.Conventions.ForeignKeyPrimitivePropertyAttributeConvention.Apply(PropertyInfo memberInfo, ConventionTypeConfiguration configuration, ForeignKeyAttribute attribute)
   at System.Data.Entity.ModelConfiguration.Conventions.PropertyAttributeConfigurationConvention`1.<.ctor>b__0(ConventionTypeConfiguration ec)
   at System.Data.Entity.ModelConfiguration.Conventions.TypeConvention.ApplyCore(Type memberInfo, ModelConfiguration modelConfiguration)
   at System.Data.Entity.ModelConfiguration.Conventions.TypeConventionBase.Apply(Type memberInfo, ModelConfiguration modelConfiguration)
   at System.Data.Entity.ModelConfiguration.Configuration.ConventionsConfiguration.ApplyModelConfiguration(Type type, ModelConfiguration modelConfiguration)
   at System.Data.Entity.ModelConfiguration.Conventions.Convention.ApplyModelConfiguration(Type type, ModelConfiguration modelConfiguration)
   at System.Data.Entity.ModelConfiguration.Configuration.ConventionsConfiguration.ApplyModelConfiguration(Type type, ModelConfiguration modelConfiguration)
   at System.Data.Entity.ModelConfiguration.Mappers.TypeMapper.MapEntityType(Type type)
   at System.Data.Entity.ModelConfiguration.Mappers.NavigationPropertyMapper.Map(PropertyInfo propertyInfo, EntityType entityType, Func`1 entityTypeConfiguration)
   at System.Data.Entity.ModelConfiguration.Mappers.TypeMapper.MapEntityType(Type type)
   at System.Data.Entity.ModelConfiguration.Mappers.NavigationPropertyMapper.Map(PropertyInfo propertyInfo, EntityType entityType, Func`1 entityTypeConfiguration)
   at System.Data.Entity.ModelConfiguration.Mappers.TypeMapper.MapEntityType(Type type)
   at System.Data.Entity.DbModelBuilder.<>c__DisplayClassd.<MapTypes>b__7(Type type)
   at System.Linq.Enumerable.WhereListIterator`1.MoveNext()
   at System.Data.Entity.Utilities.IEnumerableExtensions.Each[T](IEnumerable`1 ts, Action`1 action)
   at System.Data.Entity.DbModelBuilder.MapTypes(EdmModel model)
   at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo)
   at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
   at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
   at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
   at System.Data.Entity.Internal.LazyInternalContext.get_ModelBeingInitialized()
   at System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbContext context, XmlWriter writer)
   at System.Data.Entity.Utilities.DbContextExtensions.<>c__DisplayClass1.<GetModel>b__0(XmlWriter w)
   at System.Data.Entity.Utilities.DbContextExtensions.GetModel(Action`1 writeXml)
   at System.Data.Entity.Utilities.DbContextExtensions.GetModel(DbContext context)
   at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext, DatabaseExistenceState existenceState)
   at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration)
   at System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.GetMigrator()
   at System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.Run()
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.AppDomain.DoCallBack(CrossAppDomainDelegate callBackDelegate)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Run(BaseRunner runner)
   at System.Data.Entity.Migrations.Design.ToolingFacade.Update(String targetMigration, Boolean force)
   at System.Data.Entity.Migrations.UpdateDatabaseCommand.<>c__DisplayClass2.<.ctor>b__0()
   at System.Data.Entity.Migrations.MigrationsDomainCommand.Execute(Action command)
Sequence contains more than one element

SystemUser类:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;

namespace Muro.Models
{
    [Table("Users")]
    public class SystemUser : CSAMLib.Security.User
    {
        public bool ClientUser { get; set; }

        [Display(Name = "Company")]
        [ForeignKey("Company")]
        public Int64? CompanyID { get; set; }
        public virtual Company Company { get; set; }

        public new ICollection<SystemUserRole> UserRoles
        {
            get;
            set;
        }


        public SystemUser CreateNewUser(string userName, string emailAddress, string firstName, string lastName)
        {
            var user = new Muro.Models.SystemUser();
            user.Login = userName;
            user.EmailAddress = emailAddress;
            user.Active = false;
            user.CurrentlyLoggedIn = false;
            user.FirstName = firstName;
            user.LastName = lastName;
            return user;
        }
    }
}

的DbContext:

public DbSet<SystemUser> Users { get; set; }

有没有人看过相同的行为并有任何提示可以解决这个问题?

谢谢!

2 个答案:

答案 0 :(得分:0)

我认为第一个问题与第二个问题无关(因为你已经解决了这个问题)。

例外情况告诉您问题应该是什么:
您在一个似乎有多个项目的集合上调用SingleOrDefault(),此方法不允许这样做。您可以执行以下操作来解决此问题:

  • 使用FirstOrDefault获取与
  • 匹配的集合的第一个元素
  • 调整搜索模式,使其仅返回零或一个元素

如果您向我们展示了对SingleOrDefault的实际通话,我们可以为您提供更好的帮助,但我无法在发布的代码中找到这样的电话......

答案 1 :(得分:0)

这是因为您的类与[Table()]属性具有相同的值,尽管您重命名了类,但您尝试创建两个具有相同名称的表,这会导致“Sequence包含多个元素”< / p>