using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.Data.SqlClient;
public static void Main()
using (var context = new EntityContext())
context.Database.EnsureCreated();
var reader = new DocumentDataReader(GetDocuments());
var bulkOperation = new BulkOperation();
bulkOperation.Connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServer());
bulkOperation.Connection.Open();
bulkOperation.DestinationTableName = "Document";
bulkOperation.BulkInsert(reader);
using (var context = new EntityContext())
FiddleHelper.WriteTable("Documents:", context.Documents);
private static IEnumerable<Document> GetDocuments()
for (var n = 0; n < 50; n++)
yield return new Document
Contents = "Contents_" + n
public class EntityContext : DbContext
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
optionsBuilder.UseSqlServer(new SqlConnection(FiddleHelper.GetConnectionStringSqlServer()));
base.OnConfiguring(optionsBuilder);
public DbSet<Document> Documents { get; set; }
public long Id { get; set; }
public string Code { get; set; }
[StringLength(int.MaxValue)]
public string Contents { get; set; }
public class DocumentDataReader : BaseDataReader<Document>
public DocumentDataReader(IEnumerable<Document> enumerables)
this.Enumerator = enumerables.GetEnumerator();
Tuples.Add(new Tuple<string, int>("Id", 0));
Tuples.Add(new Tuple<string, int>("Code", 1));
Tuples.Add(new Tuple<string, int>("Contents", 2));
public override object this[string name]
return Enumerator.Current.Id;
return Enumerator.Current.Code;
else if(name == "Contents")
return Enumerator.Current.Contents;
throw new Exception("Invalid name");
public class BaseDataReader<T> : IDataReader
protected IEnumerator<T> Enumerator { get; set; }
public List<Tuple<string, int>> Tuples = new List<Tuple<string, int>>();
get { return Tuples.Count; }
public virtual object this[string name]
throw new NotImplementedException();
public string GetName(int i)
return Tuples.Single(x => x.Item2 == i).Item1;
public int GetOrdinal(string name)
return Tuples.Single(x => x.Item1 == name).Item2;
public object GetValue(int i)
return Enumerator.MoveNext();
#region Default Interface Implementation
public string GetDataTypeName(int i)
throw new NotImplementedException();
public Type GetFieldType(int i)
throw new NotImplementedException();
public int GetValues(object[] values)
throw new NotImplementedException();
public bool GetBoolean(int i)
throw new NotImplementedException();
public byte GetByte(int i)
throw new NotImplementedException();
public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length)
throw new NotImplementedException();
public char GetChar(int i)
throw new NotImplementedException();
public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length)
throw new NotImplementedException();
public Guid GetGuid(int i)
throw new NotImplementedException();
public short GetInt16(int i)
throw new NotImplementedException();
public int GetInt32(int i)
throw new NotImplementedException();
public long GetInt64(int i)
throw new NotImplementedException();
public float GetFloat(int i)
throw new NotImplementedException();
public double GetDouble(int i)
throw new NotImplementedException();
public string GetString(int i)
throw new NotImplementedException();
public decimal GetDecimal(int i)
throw new NotImplementedException();
public DateTime GetDateTime(int i)
throw new NotImplementedException();
public IDataReader GetData(int i)
throw new NotImplementedException();
public bool IsDBNull(int i)
throw new NotImplementedException();
public object this[int i] => throw new NotImplementedException();
public DataTable GetSchemaTable()
throw new NotImplementedException();
throw new NotImplementedException();
public int Depth { get; }
public bool IsClosed { get; }
public int RecordsAffected { get; }