How to ensure type in dynamic inheritance - c#-3.0

I have the following code:
public abstract class A //(a)
{
public dynamic Id { get; set; }
}
public class B: A
{
...
}
public class C:A
{
...
}
How can I make it so that B.Id is an int and C.Id is always a string?

public abstract class A<T> //(a)
{
public T Id { get; set; }
}
public class B: A<int>
{
...
}
public class C:A<String>
{
...
}

Related

Map an Entity iEnumerator To Dto Enumerator

I am using CQRS. I select my Entities IEnumerator from database and i want to map this to my Dto class.
My Dto class:
public class XCollectionDto
{
public IEnumerable<XReadDto> Entries { get; init; } = Enumerable.Empty<XReadDto>();
}
My mapper class:
public class XReadMapper : IEntityToDtoMapper<X, XCollectionDto>
{
public XCollectionDto Map(IEnumerable <X> source, XCollectionDto target)
{
//todo
Here i want to map source to target Entries list
}
}
How can i do that, without a for loop? I am not using AutoMaper, the mapping is manual
I think you could accompish your purpose with C# reflection
I created the two class for test:
public class somemodel
{
public int Id { get; set; }
public string Name { get; set; }
public List<int> Numlist { get; set; }
}
public class somemodelDTO
{
public int Id { get; set; }
public string SomeName { get; set; }
public List<int> Numlist { get; set; }
}
the method to bind properties of somemodelDTO which have the same name with properties of somemodel:
private static somemodelDTO GetMap<somemodel, somemodelDTO>(somemodel some)
{
somemodelDTO somemDTO = Activator.CreateInstance<somemodelDTO>();
var typesource = some.GetType();
var typedestination = typeof(somemodelDTO);
foreach(var sp in typesource.GetProperties())
{
foreach( var dp in typedestination.GetProperties())
{
if(sp.Name==dp.Name)
{
dp.SetValue(somemDTO, sp.GetValue(some, null), null);
}
}
}
return somemDTO;
}
The result:

EF Core second object reference generates circular dependency

Is it not possible to have a second reference to second class? FirstClass contains SecondClasses and SeocondBegin containing the begin element. With this code I get the execption in SaveChanges:
System.InvalidOperationException: 'Unable to save changes because a circular dependency was detected in the data to be saved: 'FirstClass { 'Id': -2147482647 } [Added] <-
SecondClasses FirstClass { 'FirstClassId': -2147482647 } SecondClass { 'Id': -2147482647 } [Added] <-
SecondBegin { 'SecondBeginId': -2147482647 } FirstClass { 'Id': -2147482647 } [Added]'.'
I would like the have this property because the second class should be a 'linked list' and the collection SecondClasses does not containing the
The source is:
namespace EFTestApp
{
public class FirstClass
{
public int Id { get; set; }
public int? SecondBeginId { get; set; }
public string Name { get; set; }
[ForeignKey(nameof(SecondBeginId))]
public SecondClass SecondBegin { get; set; }
[InverseProperty(nameof(EFTestApp.SecondClass.FirstClass))]
[IgnoreDataMember]
public ICollection<SecondClass> SecondClasses { get; set; }
}
}
namespace EFTestApp
{
public class SecondClass
{
public int Id { get; set; }
public int FirstClassId { get; set; }
public string Url { get; set; }
[ForeignKey(nameof(FirstClassId))]
public FirstClass FirstClass { get; set; }
public SecondClass Next { get; set; }
}
}
namespace EFTestApp
{
public class ApplicationDbContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.EnableSensitiveDataLogging();
optionsBuilder.UseSqlServer(#"Server=(localdb)\MSSQLLocalDB;Database=sample;Trusted_Connection=True");
}
public DbSet<FirstClass> FirstClasses { get; set; }
public DbSet<SecondClass> SecondClasses { get; set; }
}
}
namespace EFTestApp
{
class Program
{
static void Main(string[] args)
{
var dbContext = new ApplicationDbContext();
dbContext.Database.EnsureCreated();
var firstClass = new FirstClass()
{
Name = "First"
};
var secondClass = new SecondClass()
{
FirstClass = firstClass,
Url = "Blablah"
};
firstClass.SecondBegin = secondClass;
dbContext.Add(firstClass);
dbContext.SaveChanges();
}
}
}
It's fine to have a cycle, but you can't create it with a single call to SaveChanges() as EF isn't able to INSERT either row without the other.
You'll have to call SaveChanges twice here, once to insert the entities, and then again to "close" the cycle.
Eg
dbContext.Add(firstClass);
dbContext.Add(secondClass);
dbContext.SaveChanges();
firstClass.SecondBegin = secondClass;
dbContext.SaveChanges();

EF Core 5 and FromSqlRaw with inheritance

I want to use a FromSqlRaw query with view models and inheritance between them.
I created two example view models:
public class SummaryVM
{
public int Quantity { get; set; }
public int Value { get; set; }
}
public class DistrictVM : SummaryVM
{
public string DistrictName { get; set; }
}
My DbContext has this content:
public DbSet<SummaryVM> SummaryVMs { get; set; }
public DbSet<DistrictVM> DistrictVMs { get; set; }
...
modelBuilder.Entity<SummaryVM>().HasNoKey();
My query:
return await _context.DistritVMs.FromSqlRaw(query).ToListAsync();
but I get an error:
SqlException: Invalid column name 'Discriminator'. Invalid column name 'DistrictName'
I know this is due to the TPH pattern and I can solve this problem if I do not use inheritance yet how I can use these two tables with inheritance without TPH, please?
SOLUTION
I had to create a base class which is not registered as entity:
public abstract BaseClass
{
public int Quantity { get; set; }
public int Value { get; set; }
}
public class SummaryVM : BaseClass
{
}
public class DistrictVM : BaseClass
{
public string DistrictName { get; set; }
}
SOLUTION
I had to create a base class which is not registered as entity:
public abstract BaseClass
{
public int Quantity { get; set; }
public int Value { get; set; }
}
public class SummaryVM : BaseClass
{
}
public class DistrictVM : BaseClass
{
public string DistrictName { get; set; }
}

SetValue to properites from inherited class

I need to create a generic set accesor where i can pass the classname.classname.property and the value to be set.
I saw this question and has been answered but i can't implement it on my project.
link is Is it possible to pass in a property name as a string and assign a value to it?
In the sample code below, how can SetValue set a value for length and width?
public interface MPropertySettable { }
public static class PropertySettable {
public static void SetValue<T>(this MPropertySettable self, string name, T value) {
self.GetType().GetProperty(name).SetValue(self, value, null);
}
}
public class Foo : MPropertySettable {
public Taste Bar { get; set; }
public int Baz { get; set; }
}
public class Taste : BarSize {
public bool sweet {get; set;}
public bool sour {get; set;}
}
public class BarSize {
public int length { get; set;}
public int width { get; set;}
}
class Program {
static void Main() {
var foo = new Foo();
foo.SetValue("Bar", "And the answer is");
foo.SetValue("Baz", 42);
Console.WriteLine("{0} {1}", foo.Bar, foo.Baz);
}
}
You are trying to set a string value to a Taste object.
It works fine using a new instance of Taste
class Program {
static void Main() {
var foo = new Foo();
foo.SetValue("Bar", new Taste());
foo.SetValue("Baz", 42);
Console.WriteLine("{0} {1}", foo.Bar, foo.Baz);
}
}
It will work if BarSize would derive from MPropertySettable.
public interface MPropertySettable { }
public static class PropertySettable
{
public static void SetValue<T>(this MPropertySettable self, string name, T value) {
self.GetType().GetProperty(name).SetValue(self, value, null);
}
}
public class Foo : MPropertySettable
{
public Taste Bar { get; set; }
public int Baz { get; set; }
}
public class Taste : BarSize
{
public bool sweet { get; set; }
public bool sour { get; set; }
}
public class BarSize : MPropertySettable
{
public int length { get; set; }
public int width { get; set; }
}
class Program
{
static void Main() {
var barSize = new BarSize();
barSize.SetValue("length", 100);
barSize.SetValue("width", 42);
Console.WriteLine("{0} {1}", barSize.length, barSize.width);
}
}

code first with abstract class, the fk couldn't generated

please look at the code below.
class Program
{
static void Main(string[] args)
{
using (myContext context = new myContext())
{
Team t = new Team();
t.id = 1;
t.Name = "asd";
context.teamSet.Add(t);
context.SaveChanges();
}
}
}
public abstract class Base
{
public virtual int id { get; set; }
}
public abstract class Player : Base
{
public virtual string Name { get; set; }
public virtual int Number { get; set; }
public virtual Team team { get; set; }
[ForeignKey("team")]
public int teamId { get; set; }
}
public class Team : Base
{
public ICollection<Player> Players { get; set; }
public string Name { get; set; }
}
public class FootballPlayer : Player
{
public double Speed { get; set; }
}
public class BasketballPlayer : Player
{
public double Height { get; set; }
public double Speed { get; set; }
}
public class myContext : DbContext
{
public DbSet<Player> playerSet { get; set; }
public DbSet<Team> teamSet { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new BaseConfiguration()).Add(new PlayerConfiguration()).Add(new TeamConfiguration()).Add(new FootballConfiguration()).Add(new BasketballConfiguration());
}
}
public class BaseConfiguration : EntityTypeConfiguration<Base>
{
public BaseConfiguration()
{
HasKey(k => k.id);
Property(p => p.id).IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
}
}
public class PlayerConfiguration : EntityTypeConfiguration<Player>
{
public PlayerConfiguration()
{
Map(p=>{
p.MapInheritedProperties();
p.ToTable("Player");
});
}
}
public class TeamConfiguration : EntityTypeConfiguration<Team>
{
public TeamConfiguration()
{
Map(p =>
{
p.MapInheritedProperties();
p.ToTable("Team");
});
}
}
public class FootballConfiguration : EntityTypeConfiguration<FootballPlayer>
{
public FootballConfiguration()
{
ToTable("FootballPlayer");
}
}
public class BasketballConfiguration : EntityTypeConfiguration<BasketballPlayer>
{
public BasketballConfiguration()
{
ToTable("BasketballPlayer");
}
}
My Player class and Team Class are derived from Based Class, and FootballPlayer and BasketballPlayer are derived from Player. But in the generated database, Player table doesn't contain a FK teamId, it is only a common property. Furthermore, the FootballPlayer and BasketballPlayer tables don't contains the properties which derived from Player class. Anyone can help?
What inheritance mapping are you trying to achieve? At the moment you have TPC between Base and Player and TPT between Player and its derived types. If you want to have inherited properties in those derived types you must use TPC as well but in such case there should be no Player table in your database. To use TPC for player you must use MapInheritedProperties in their mapping configurations.