Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to Run Code First Seed Method - Sequence contains more than one element

I am unable to insert records to a table, receiving the error Sequence contains more than one element. The Entity that I want to add inherits from another table in a Table Per Hierachy (TPH) relationship like to.

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; }
    }

Then, this Entity extends the above Entity like so

  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; }

    }

From this above, Entity Framework created a Reward Table like so (Please note that two other classes extend the Reward class but I am focused only on the Cash Reward Class/Entity)

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

I am trying to add two records of type CashReward using EF Code First Seed method like so:

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

And I am getting error message

Running Seed method.

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)

Please help of point me to the right direction. Thanks for your time

like image 978
Val Okafor Avatar asked Oct 17 '13 18:10

Val Okafor


2 Answers

The stack trace shows that the exception comes from

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

And the exception is thrown while executing AddOrUpdate. This is because AddOrUpdate expects an expression that uniquely identifies the object of which is has to decide whether it should be added or updated. This simply means you've got more than one CashReward in the database with the names you try to add.

BTW, you can also do

context.Reward.AddOrUpdate(p => p.RewardName, cashRewards.ToArray());
like image 143
Gert Arnold Avatar answered Nov 03 '22 18:11

Gert Arnold


It appears that you may have a duplicate business name in your query. Try replacing your call .Single with .FirstOrDefault

FirstOrDefault will return the first matching element and null if none is found.

like image 3
gleng Avatar answered Nov 03 '22 18:11

gleng