简体   繁体   中英

The entity type 'List<string>' requires a primary key to be defined

Getting "The entity type List<string'> requires a primary key to be defined." using .NET 6 to build a Web API.

The following is my Model class defining "Sales":

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace SalesAPI.Data
{
    public class SalesItem
    {
     
        [Key]
        [Required]
        public Guid UserID { get; set; }

        [Required]
        [MinLength(5)]
        [MaxLength(75)]
        public String Title { get; set; }  = String.Empty;

        [Required]
        [MinLength(5)]
        public String Description { get; set; } = String.Empty;

        public List<String> Images { get; set; } = new List<String>();

        [Required]
        public DateTime ListingTime { get; set; }

        public String Location { get; set; } = String.Empty;

        public String ContactInfo { get; set; } = String.Empty;
    }
}

The following is my DBContext class:

using Microsoft.EntityFrameworkCore;
using SalesAPI.Controllers;
    
namespace SalesAPI.Data
{
    public class DataContext : DbContext
    {
        public DataContext(DbContextOptions<DataContext> options) : base(options) { }

        public DbSet<SalesItem> SalesItems { get; set; }
        
    }
}

You'll have to make sure you have a table for the

public List<String> Images { get; set; } = new List<String>

since the database isn't able to reference an unknown list size in the table created.

Change

public List<String> Images { get; set; } = new List<String>

To

public List<ImageUri> Images { get; set; } = new List<ImageUri>

and create a class.

public class ImageUri
{
    [Key]
    public int Id { get; set; }
    public string Uri { get; set; } = null!;
}

You can convert the List into a delimited string and use it that way instead of having to create a special class to basically hold a string.

modelBuilder.Entity<Berk>(x =>
{
    x.HasKey(y => y.BerkId);
    x.Property(y => y.TheList)
        .HasConversion(
            from => string.Join(";", from),
            to => string.IsNullOrEmpty(to) ? new List<string>() : to.Split(';', StringSplitOptions.RemoveEmptyEntries).ToList(),
            new ValueComparer<List<string>>(
                (c1, c2) => c1.SequenceEqual(c2),
                c => c.Aggregate(0, (a, v) => HashCode.Combine(a, v.GetHashCode())),
                c => c.ToList()
        )
    );
});

public class Berk
{
    [Key]
    public int BerkId { get; set; }
    public List<string> TheList { get; set; }
}

The HasConversion has the value stored as a delimited string in the db, splits it to the List when you are using it and then joins it back again when saving. Just pick a delimiter that will not be in any of your strings.

This was bugging me this afternoon, hope it helps someone else.

We encountered this issue when extending an EF generated model via partial class. The partial class included two properties that were not reflective of the underlying data.table and generated the error: "entity type 'list' requires a primary key to be defined". In the end, our solution was to include the [NotMapped] attribute as follows:

 [NotMapped] public List<string> Roles { get; set; } = new List<string>(); [NotMapped] public List<string[]> Claims { get; set; } = new List<string[]>();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM