//#define EFCore2

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace EFCore3
{
	public class MyContext : DbContext
	{
		public DbSet<Owner> Owners => Set<Owner>();
		public DbSet<Dog> Dogs => Set<Dog>();

		protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
		{
			base.OnConfiguring(optionsBuilder);

			optionsBuilder
				.EnableDetailedErrors()
#if !EFCore2
				.UseLoggerFactory(Program.MyLoggerFactory)
#endif
				.UseSqlServer(@"server=(localdb)\mssqllocaldb;database=DogOwners;Integrated Security=true;ConnectRetryCount=0")
				;
		}

		protected override void OnModelCreating(ModelBuilder modelBuilder)
		{
			base.OnModelCreating(modelBuilder);

			foreach (var entity in modelBuilder.Model.GetEntityTypes())
			{
				foreach (var property in entity.GetProperties())
				{
					if (property.ClrType == typeof(string))
					{
						property.SetMaxLength(100);
					}
				}
			}

			modelBuilder.Entity<Owner>().Property(x => x.FirstName).HasField("_firstName");

			//modelBuilder.Entity<PropertyBagEntity>(c =>
			//{
			//	c.Property<int>("Id");
			//	c.Property<string>("Name");
			//});

#if EFCore2
			modelBuilder.Query<MyStupidQueryType>().ToQuery(() => Dogs.Select(x => new MyStupidQueryType() { Name = x.Name }));
#endif
#if !EFCore2
			modelBuilder.Entity<MyStupidQueryType>().HasNoKey().ToQuery(() => Dogs.Select(x => new MyStupidQueryType() { Name = x.Name }));
#endif
		}
	}

	public class Owner
	{
		public int Id { get; set; }
		// modelBuilder.UsePropertyAccessMode(PropertyAccessMode.PreferFieldDuringConstruction);
		string _firstName;
		public string FirstName
		{
			get { Debugger.Break(); return _firstName; }
			set { Debugger.Break(); _firstName = value; }
		}
		public string LastName { get; set; }
		public ICollection<Dog> Dogs { get; set; }
	}

	public class Dog
	{
		public int Id { get; set; }
		public string Name { get; set; }
		public DateTime DateOfBirth { get; set; }
		public int OwnerId { get; set; }
		public Owner Owner { get; set; }
	}

	public class MyStupidQueryType
	{
		public string Name { get; set; }
	}

	//public class PropertyBagEntity
	//{
	//	public object this[string propertyName]
	//	{
	//		get => null;
	//		set { }
	//	}
	//}
}
