Skip to Main Content

ODP.NET

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

EF Core 3.1 Beta OracleException: ORA-01460

user606112Jul 12 2020 — edited Jul 16 2020

Adding an image and saving the context ORA-01460 occurs.

DB-Set in Model:

public class Picture

{

    public int PictureID { get; set; }

    public byte\[\] Bild { get; set; }

    public DateTime Ludsys { get; set; }

    public int OrderDetailID { get; set; }

    public OrderDetail OrderDetail { get; set; } // Navigationseigenschaft

} // Picture

Table in DB:

Table in ORA DB.JPG

If I load the image and save it with SQL-Developer it can be read and displayed in the application.

Create the picture:

...

picture = new Picture

{

 Bild = null,

 Ludsys = DateTime.Now,

 OrderDetail = orderdetail

}; // picture

imgBild.DataContext = picture;

imgBild.Source = FileToBitmapImage(dlg.FileName); // Bild aus Filesystem laden und anzeigen

context.Pictures.Add(picture);

pictures.Add(picture);

ind = pictures.Count - 1; // Index für den neuen Datensatz ist pictures.Count - 1

...

    private BitmapImage FileToBitmapImage(string source)

    {

        try

        {

            if (source == string.Empty) { return null; }

            BitmapImage bitmapimage = new BitmapImage();

            using FileStream filestream = File.Open(source, FileMode.Open);

            bitmapimage.BeginInit();

            bitmapimage.CacheOption = BitmapCacheOption.OnLoad;

            bitmapimage.StreamSource = filestream;

            bitmapimage.EndInit();

            return bitmapimage;

        } // try

        catch (Exception ex)

        {

            MessageBox.Show(ex.Message, "Nachricht", MessageBoxButton.OK, MessageBoxImage.Error);

            return null;

        } // catch

    } // FileToBitmapImage

ImageConverter:

     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

    {

        try

        {

            if (value == null) { return null; }

            byte\[\] byteArray = (byte\[\])value;

            using MemoryStream memorystream = new MemoryStream(byteArray);

            BitmapImage bitmapimage = new BitmapImage();

            bitmapimage.BeginInit();

            bitmapimage.CacheOption = BitmapCacheOption.OnLoad;

            bitmapimage.StreamSource = memorystream;

            bitmapimage.EndInit();

            return bitmapimage;

        } // try

        catch (Exception)

        {

            return null;

        } // catch

    } // Convert

    // ConvertBack (Ziel -> Quelle)

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

    {

        try

        {

            if (value == null) { return null; }

            ImageSource imagesource = (ImageSource)value;

            BitmapSource bitmapsource = imagesource as BitmapSource;

            BitmapEncoder encoder = new JpegBitmapEncoder();

            encoder.Frames.Add(BitmapFrame.Create(bitmapsource));

            using MemoryStream ms = new MemoryStream();

            encoder.Save(ms);

            byte\[\] bytearray = ms.ToArray();

            return bytearray;

        } // try

        catch (Exception)

        {

            return null;

        } // catch

    } // ConvertBack
This post has been answered by Alex Keh-Oracle on Jul 14 2020
Jump to Answer

Comments

Alex Keh-Oracle

Did you add the required Fluent API (i.e. HasMaxLength(x > 2000)) so that ODP.NET EF Core can map a byte[] to a BLOB?

user606112

My fluent API looks like this:

        protected override void OnModelCreating(ModelBuilder modelBuilder)

        {

            //Default - Schema: HR

            modelBuilder.HasDefaultSchema("HR");

            // Customer-Configuration

            modelBuilder.Entity<Customer>().Property(c => c.CompanyName).HasColumnType("varchar2");

            modelBuilder.Entity<Customer>().Property(c => c.CompanyName).HasMaxLength(40);

            modelBuilder.Entity<Customer>().Property(c => c.Ludsys).IsConcurrencyToken();

            // Order-Configuration

            modelBuilder.Entity<Order>().Property(o => o.Ludsys).IsConcurrencyToken();

            // OrderDetail-Configuration

            modelBuilder.Entity<OrderDetail>().Property(od => od.Ludsys).IsConcurrencyToken();

            // Product-Configuration

            modelBuilder.Entity<Product>().Property(p => p.ProductName).HasColumnType("varchar2");

            modelBuilder.Entity<Product>().Property(p => p.ProductName).HasMaxLength(40);

            modelBuilder.Entity<Product>().Property(p => p.Ludsys).IsConcurrencyToken();

            // Picture-Configuration

            modelBuilder.Entity<Picture>().Property(p => p.Bild).HasColumnType("blob");

            modelBuilder.Entity<Product>().Property(p => p.ProductName).HasMaxLength(6000000); // 6MB

            modelBuilder.Entity<Picture>().Property(p => p.Ludsys).IsConcurrencyToken();

            // Beziehungen der DbSets untereinander

            modelBuilder.Entity<Customer>().HasMany(c => c.Orders).WithOne(o => o.Customer);

            modelBuilder.Entity<Order>().HasMany(o => o.OrderDetails).WithOne(od => od.Order);

            modelBuilder.Entity<OrderDetail>().HasMany(od => od.Pictures).WithOne(p => p.OrderDetail);

            modelBuilder.Entity<Product>().HasMany(p => p.OrderDetails).WithOne(od => od.Product);

        } // OnModelCreating

Alex Keh-Oracle

Have you tried adding the required HasMaxLength(x > 2000) Fluent API to the following line:

       modelBuilder.Entity<Picture>().Property(p => p.Bild).HasColumnType("blob");

This Fluent API is required as per the documentation.

user606112

I tried 3 variants:

only: modelBuilder.Entity<Picture>().Property(p => p.Bild).HasColumnType("blob");

           

only: modelBuilder.Entity<Product>().Property(p => p.ProductName).HasMaxLength(6000000); // 6MB

both: modelBuilder.Entity<Picture>().Property(p => p.Bild).HasColumnType("blob");

         modelBuilder.Entity<Product>().Property(p => p.ProductName).HasMaxLength(6000000); // 6MB

I get always: ORA-01460

Alex Keh-Oracle
Answer

Have you tried the HasMaxLength on the Bild property, not the ProductName?

modelBuilder.Entity<Picture>().Property(p => p.Bild).HasMaxLength(6000000);

It should work with the HasMaxLength, but without the HasColumnType.

Marked as Answer by user606112 · Sep 27 2020
user606112

Hallo Alex,

thank you very much for your help. Only the following property is necessary.

modelBuilder.Entity<Picture>().Property(p => p.Bild).HasMaxLength(6000000);

I did much copy and paste to resolve the problem, so that I didn't see the wrong columnname "productname".

Now all is working pretty .

With kind regards! Günter Hoormann

Alex Keh-Oracle

Hi Gunter,

Glad to hear it works for you. Which DB version are you using?

My team hadn't seen this error before when we tested similar scenarios.

user606112

Hallo Alex,

I use DB-Version as below to create my Test-DB:

BANNER

-------------------------------------------------------------------

Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production

BANNER_FULL

-------------------------------------------------------------------

Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production

Version 18.4.0.0.0

BANNER_LEGACY

-------------------------------------------------------------------

Oracle Database 18c Express Edition Release 18.0.0.0.0 - Production

I created the DB by application in VisualStudio 2019 using the following nuget-packages:

Util1.JPG

DB looks like this:

Util3.JPG

Util4.JPG

I tested EF Core 3.1 using packages:

Util2.JPG

Actual Fluent-API:

    protected override void OnModelCreating(ModelBuilder modelBuilder)

    {

        //Default - Schema: HR

        modelBuilder.HasDefaultSchema("HR");

        // Customer-Configuration

        modelBuilder.Entity\<Customer>().Property(c => c.CompanyName).HasMaxLength(40);

        modelBuilder.Entity\<Customer>().Property(c => c.Ludsys).IsConcurrencyToken();

        // Order-Configuration

        modelBuilder.Entity\<Order>().Property(o => o.Ludsys).IsConcurrencyToken();

        // OrderDetail-Configuration

        modelBuilder.Entity\<OrderDetail>().Property(od => od.Ludsys).IsConcurrencyToken();

        // Product-Configuration

        modelBuilder.Entity\<Product>().Property(p => p.ProductName).HasMaxLength(40);

        modelBuilder.Entity\<Product>().Property(p => p.Ludsys).IsConcurrencyToken();

        //Picture - Configuration

        modelBuilder.Entity\<Picture>().Property(p => p.Bild).HasMaxLength(6000000); // 6MB

        modelBuilder.Entity\<Picture>().Property(p => p.Ludsys).IsConcurrencyToken();

        // Beziehungen der DbSets untereinander

        modelBuilder.Entity\<Customer>().HasMany(c => c.Orders).WithOne(o => o.Customer);

        modelBuilder.Entity\<Order>().HasMany(o => o.OrderDetails).WithOne(od => od.Order);

        modelBuilder.Entity\<OrderDetail>().HasMany(od => od.Pictures).WithOne(p => p.OrderDetail);

        modelBuilder.Entity\<Product>().HasMany(p => p.OrderDetails).WithOne(od => od.Product);

    } // OnModelCreating

For ludsys column I created some trigger like this:

-- Customers

create or replace trigger trg_Customers_Ludsys

before insert or update on "Customers"

for each row

begin

:new."Ludsys" := sysdate;

end trg_Customers_Ludsys;

/

I hope this will help you.

Günter

1 - 8

Post Details

Added on Jul 12 2020
8 comments
740 views