无法运行代码优先种子方法 - 序列包含多个元素

时间:2013-10-17 18:53:30

标签: c# entity-framework

我无法将记录插入表中,接收错误序列包含多个元素。 我要添加的实体继承自Table Per Hierachy(TPH)关系中的另一个表,如。

public abstract class Reward
    {
        public int RewardId { get; set; }

        [Display(Name = "Retailer")]
        public int RetailerId { get; set; }

        [Display(Name = "Reward Name")]
        public string RewardName { get; set; }

        [Display(Name = "Start Date")]
        [DataType(DataType.DateTime)]
        public DateTime StartDate { get; set; }

        [Display(Name = "Start Date")]
        [DataType(DataType.DateTime)]
        public DateTime EndDate { get; set; }


        public string Description { get; set; }
        public Boolean Status { get; set; }

        [Display(Name = "Reward Type")]
        public Enums.RewardType RewardType { get; set; }

        public ICollection<Customer> EnrolledCustomers { get; set; }
        public virtual Retailer BusinessName { get; set; }
    }

然后,这个实体扩展了上面的实体

  public class CashReward : Reward
    {

        [Display(Name = "Default Cash Value")]
        public double DefaultCashValue { get; set; }

        [Display(Name = "X Value - Amount Spent")]
        public decimal XAmountSpent { get; set; }

        [Display(Name = "Y Value - Amount Earned")]
        public decimal YAmountEarned { get; set; }

    }

从上面可以看出,Entity Framework创建了一个类似的奖励表(请注意,其他两个类扩展了奖励类,但我只关注现金奖励类/实体)

CREATE TABLE [dbo].[Rewards] (
    [RewardId]                   INT             IDENTITY (1, 1) NOT NULL,
    [RetailerId]                 INT             NOT NULL,
    [RewardName]                 NVARCHAR (MAX)  NULL,
    [StartDate]                  DATETIME        NOT NULL,
    [EndDate]                    DATETIME        NOT NULL,
    [Description]                NVARCHAR (MAX)  NULL,
    [Status]                     BIT             NOT NULL,
    [RewardType]                 INT             NOT NULL,
    [DefaultCashValue]           FLOAT (53)      NULL,
    [XAmountSpent]               DECIMAL (18, 2) NULL,
    [YAmountEarned]              DECIMAL (18, 2) NULL,
    [DefaultValue]               INT             NULL,
    [CurrentNumberOfTransaction] INT             NULL,
    [TargetNumberOfTransaction]  INT             NULL,
    [GetYFree]                   INT             NULL,
    [DefaultPointsValue]         BIGINT          NULL,
    [XAmountSpent1]              DECIMAL (18, 2) NULL,
    [YPointsEarned]              BIGINT          NULL,
    [Discriminator]              NVARCHAR (128)  NOT NULL,
    CONSTRAINT [PK_dbo.Rewards] PRIMARY KEY CLUSTERED ([RewardId] ASC),
    CONSTRAINT [FK_dbo.Rewards_dbo.Retailers_RetailerId] FOREIGN KEY ([RetailerId]) REFERENCES [dbo].[Retailers] ([RetailerId]) ON DELETE CASCADE

我正在尝试使用EF Code First Seed方法添加两个类型为CashReward的记录,如下所示:

var cashRewards = new List<Reward>
            {
                new CashReward
                {
                   RetailerId = retailers.Single( i => i.BusinessName == "Prime Lending").RetailerId,
                   RewardName = "October Fest Bonanza",
                   StartDate = DateTime.Now,
                   EndDate  = DateTime.Parse("12/23/2014"),
                   Description = "Best reward for the month of October",
                   Status = true,
                   RewardType = Enums.RewardType.CashReward,
                   DefaultCashValue = 2,
                   XAmountSpent = 20,
                   YAmountEarned = 1                 
              },

                new CashReward
                {
                   RetailerId = retailers.Single( i => i.BusinessName == "Mike Liquor Store").RetailerId,
                   RewardName = "Loyal Customer Reward",
                   StartDate = DateTime.Now,
                   EndDate  = DateTime.Parse("2/9/2014"),
                   Description = "Hope you enjoy the best reward for the month of October",
                   Status = true,
                   RewardType = Enums.RewardType.CashReward,
                   DefaultCashValue = 5,
                   XAmountSpent = 40,
                   YAmountEarned = 5                 
              },

            };

            cashRewards.ForEach(r => context.Reward.AddOrUpdate(p => p.RewardName, r));
            context.SaveChanges();

我收到错误消息

运行种子方法。

System.InvalidOperationException: Sequence contains more than one element
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__2[TResult](IEnumerable`1 sequence)
   at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle[TResult](IEnumerable`1 query, Expression queryRoot)
   at System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute[TResult](Expression expression)
   at System.Data.Entity.Internal.Linq.DbQueryProvider.Execute[TResult](Expression expression)
   at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)
   at System.Data.Entity.Migrations.DbSetMigrationsExtensions.AddOrUpdate[TEntity](DbSet`1 set, IEnumerable`1 identifyingProperties, InternalSet`1 internalSet, TEntity[] entities)
   at System.Data.Entity.Migrations.DbSetMigrationsExtensions.AddOrUpdate[TEntity](IDbSet`1 set, Expression`1 identifierExpression, TEntity[] entities)
   at ValueCard.Web.Migrations.Configuration.<>c__DisplayClass22.<Seed>b__1a(Reward r) in \Migrations\Configuration.cs:line 113
   at System.Collections.Generic.List`1.ForEach(Action`1 action)

请帮助我指出正确的方向。谢谢你的时间

2 个答案:

答案 0 :(得分:7)

堆栈跟踪显示异常来自

cashRewards.ForEach(r => context.Reward.AddOrUpdate(p => p.RewardName, r));

执行AddOrUpdate时抛出异常。这是因为AddOrUpdate期望一个唯一标识其对象的表达式必须决定是否应该添加或更新它。这只是意味着您在数据库中有多个CashReward,其中包含您尝试添加的名称。

顺便说一下,你也可以这样做

context.Reward.AddOrUpdate(p => p.RewardName, cashRewards.ToArray());

答案 1 :(得分:3)

您的查询中可能包含重复的商家名称。尝试使用.Single

替换您的通话.FirstOrDefault

FirstOrDefault将返回第一个匹配元素,如果找不到,则返回null