C
C#9mo ago
Haqz

❔ Attaching record from one of multiple tables to another's entity property.

Heya, this time i'm struggling with Entity Framework. So I have main table PaymentDatas that holds mostly irrelevant data beside numeric value of which provider the rest of the data is stored. My goal is to have some sort of computed/virtual column, that when i query PaymentData, in property provider it has rest of the data pulled from specific provider. Thanks in advance!
15 Replies
Tvde1
Tvde19mo ago
This sounds like it's possible. Could you share a bit of the code you attempted? We can help you fix up code more easy than that we can write example code
Haqz
Haqz9mo ago
Been mostly scraping internet looking for an answear, the closest i got to writing anything was:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<PaymentData>().Property(o => o.provider).HasComputedColumnSql("[FirstName] + ' ' + [LastName]");
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<PaymentData>().Property(o => o.provider).HasComputedColumnSql("[FirstName] + ' ' + [LastName]");
}
For context it's inside of my DbContext class Also, right now it yells because compiler found two similiar stuff like System.Data.Entity.DbContext and Microsoft.EntityFrameworkCore.DbContext
using Microsoft.EntityFrameworkCore;
using service__payments.Models;
using System.Data.Entity;

namespace service__payments.Helpers
{
public class DataContext : DbContext
{
public DataContext(DbContextOptions<DataContext> options) : base(options) { }
public virtual DbSet<PaymentData> PaymentDatas { get; set; } = null!;

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<PaymentData>().Property(o => o.provider).HasComputedColumnSql("[FirstName] + ' ' + [LastName]");
}
}
}
using Microsoft.EntityFrameworkCore;
using service__payments.Models;
using System.Data.Entity;

namespace service__payments.Helpers
{
public class DataContext : DbContext
{
public DataContext(DbContextOptions<DataContext> options) : base(options) { }
public virtual DbSet<PaymentData> PaymentDatas { get; set; } = null!;

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<PaymentData>().Property(o => o.provider).HasComputedColumnSql("[FirstName] + ' ' + [LastName]");
}
}
}
For better view ^
Tvde1
Tvde19mo ago
is provider another entity in your system?
Haqz
Haqz9mo ago
Yes
Tvde1
Tvde19mo ago
usually you would have
class PaymentData
{
...
public Provider CurrentProvider { get; set; }
}

class Provider
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
class PaymentData
{
...
public Provider CurrentProvider { get; set; }
}

class Provider
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
where you can do
context.PaymentDatas
.Include(payData => payData.Provider)
.ToListAsync();
context.PaymentDatas
.Include(payData => payData.Provider)
.ToListAsync();
Tvde1
Tvde19mo ago
Introduction to relationships - EF Core
How to configure relationships between entity types when using Entity Framework Core
Haqz
Haqz9mo ago
The thing is that I'll have multiple providers and they will hold different data, so let's say in the public Provider CurrentProvider { get; set; } I'll hold either of PayPal, Stripe, PayU data Thus why I'm in need of some sort of virtual/computed column
Anu6is
Anu6is9mo ago
this shouldn't change anything, as long as whatever it holds is a valid provider entity, the suggested solution should still work
Haqz
Haqz9mo ago
So basically i should create parent class Provider and inherit from it for specific providers?
Accord
Accord9mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Haqz
Haqz9mo ago
So after some time I'm coming back to this issue, i put down the idea for the time when i implement at least one of the providers. So, what i came up with is to somehow make right join call on provider tables. This per se is not hard, but I'd like to somehow attach the data to one property on the main entity, preferably i'd like it to be eager loaded. When i was still pursuing this idea i thought about having some parent class, let's say Provider and inherit it for each of the provider types. Then after that in main entity i would just have the parent class as the type for the field, but when i done that it yelled with error Attempt to acess missing function For context the code i still somewhat remember:
//the main entity
class PaymentData
{
private readonly DataContext _context;
public PaymentData(DataContext context) => _context = context;
//some basic fields
[NonMapped]
public PaymentProvider? Provider
{
get
{
return _context.StandardProvider.FirstOrDefault(x => x.PaymentId == this.Id);
}
}
}
//the main entity
class PaymentData
{
private readonly DataContext _context;
public PaymentData(DataContext context) => _context = context;
//some basic fields
[NonMapped]
public PaymentProvider? Provider
{
get
{
return _context.StandardProvider.FirstOrDefault(x => x.PaymentId == this.Id);
}
}
}
Same error was given when i changed the Provider field to type object or dynamic. Is such stuff even possible? I'm coming from Node.js enviroment so i might even have the wrong idea of how to do it. Thanks in advance again!
Tvde1
Tvde19mo ago
Data classes really shouldn't do DB queries themselves, it's way better to have a class which properties are filled by the service and maybe you need two
public class PaymentData
{
...
}


public class PaymentDataWithProvider
{
...
public Provider Provider { get; init; }
}
public class PaymentData
{
...
}


public class PaymentDataWithProvider
{
...
public Provider Provider { get; init; }
}
Haqz
Haqz9mo ago
So I should just scrap the idea of having some sort of funky magic to connect these two tables, and just merge their info? Based on the relationship of course
Tvde1
Tvde19mo ago
Yeah
Accord
Accord9mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.