简体   繁体   中英

Entity Framework Core will not map to BigInteger

I am needing to use the BigInteger class to handle large integers to my classes, however when trying to use EntityFramework Core to map to a DB table I recieve the following error:

The property AllianceRank.Reputation could not be mapped, because it is of type BigInteger which is not a supported primitive type or a valid entity type. Either explicitly map this property, or ignore it.

[Column("reputation")]
public BigInteger Reputation { get; set; }

It would seem that BigIntegers are not a supported type for mapping. How can I force it to map, or otherwise resolve this issue?

Entity Framework would have to make assumptions about how to store that. If you're using SQL server, for example, bigint doesn't work because your values could be larger or smaller than what's possible with bigint . Would varchar be more appropriate? Possibly, but if you truly mean it to be a number and not say, an identifier, asking EF to query that as a number is going to be problematic. So essentially, there are less ambiguous types like long or string where you're not leaving the guesswork on how to store it up to Entity Framework.

Only scalar types, string, and byte[] are supported. The largest scalar type available is decimal. Which "only" allows 28-29 significant digits.

Since EF Core 2.1, you can define Value Conversions when you define data models in the OnModelCreating() function of your DbContext class.

The best part is that this allows property values to be converted automatically when reading from or writing to the database!

So, in your case, you have a BigInteger property ( Reputation ) in C# and a corresponding INT(25) field in MySQL, you can do this:

var converter = new ValueConverter<BigInteger, long>(    
    model => (long)model,
    provider => new BigInteger(provider));

modelBuilder
    .Entity<AllianceRank>()
    .Property(e => e.Reputation)
    .HasConversion(converter);

PS You might actually wanna use a variable-length string type (like VARBINARY) to store the value in MySQL instead of INT(25) , as a C# BigInteger store a much larger value and therefore cause exceptions while converting to INT(25) or C# long .

Use

public Int64 FieldName { get; set; }

In your Model class, it will be "bigint" datatype in SQL

For the poor souls who receive this cryptic error message in a similar situation:

Unable to cast object of type 'System.Int64' to type 'System.Decimal'.

You would assume that Entity Framework would automatically map a SQL Server bigint (64 bit unsigned integer) to the appropriate C# long (also 64 bit unsigned integer), but noo...

So, you have to provide a bit of guidance, in the OnModelCreating(ModelBuilder modelbuilder) method of your DbContext, using HasColumnType() , like so:

using Microsoft.EntityFrameworkCore;

namespace Some.Namespace
{
    public class YourClassDbContext : DbContext
    {
        public YourClassDbContext(DbContextOptions<YourClassDbContext> options) : base(options) 
        {
        }

        public YourClassDbContext() {}

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            /* omitted stuff for PK and index */
            modelBuilder.Entity<ClassXYZ>().Property(t => t.Id).HasColumnType("long");
            
            base.OnModelCreating(modelBuilder);
        }
    

With many thanks to @Kelvin Lai above, whose answer put me on the right path, and https://docs.microsoft.com/en-us/ef/core/modeling/value-conversions

my problem solved by: by use int64 instead of biginteger

public class MyClassName
    {
        [Key]
        public Int64 TableId { get; set; }
    }

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