PetaPoco mapping properties within properties - petapoco

I am new to PetaPoco and initially I was liking it but then hit a wall which I simply dont know how to search for.
I have a object which needs to set a property within one of its properties, ie Job.Min.BaseValue. The source of this data is "min_mb".
So basically my object is not a direct mapping of the source table
public class Usage
{
public Decimal BaseValue {get;set;}
public Decimal BaseScale {get;set;}
public Decimal BaseUnit {get;set;}
}
[PetaPoco.TableName("data")]
[PetaPoco.PrimaryKey("date, client_name")]
[PetaPoco.ExplicitColumns]
public class Job
{
[PetaPoco.Column("date")]
public DateTime Date {get;set;}
[PetaPoco.Column("client_name")]
public String ClientName {get;set;}
public Usage Min {get;set;}
public CommvaultJob() { Min = new Usage() { BaseScale=1024, BaseUnit="MB" }; }
}

I think you're just missing the extra type when you call Fetch or Query. This worked for me :
Calling PetaPoco :
var allData = _db.Fetch<TestJobPoco,Usage>("select * from dataTEST");
return View( allData);
The pocos :
[PetaPoco.ExplicitColumns]
public class Usage
{
public Usage()
{
BaseScale=1024;
BaseUnit="MB";
}
[PetaPoco.Column("base_value")]
public Decimal BaseValue {get;set;}
[PetaPoco.Ignore]
public Decimal BaseScale {get;set;}
[PetaPoco.Ignore]
public string BaseUnit {get;set;}
}
[PetaPoco.TableName("dataTEST")]
[PetaPoco.PrimaryKey("id")]
[PetaPoco.ExplicitColumns]
public class TestJobPoco
{
[PetaPoco.Column("id")]
public int Id {get;set;}
[PetaPoco.Column("date")]
public DateTime Date {get;set;}
[PetaPoco.Column("client_name")]
public String ClientName {get;set;}
public Usage Min {get;set;}
public TestJobPoco()
{
//Min = new Usage() { BaseScale=1024, BaseUnit="MB" };
}
}
My test database has an id, date, client_name and base_value columns. The primary key is id so it's slightly different than yours but this shouldn't change the way the poco mapping happens.

If your objects do not map with the table structure, an ORM can't help much.
You will need to do the mapping manually or made new shadow properties that copy the values of the other fields, but this added complexity will defeat the purpose of an ORM.

Related

Designing a hierarchy of abstract classes and using it in EF Core

I am using .NET Core with Entity Framework Core to build a finance app and I want to know how to make my design better.
I have a 1 to Many relationship between two entities, BankAccount and Transaction. In a way that:
1 Account can have many Transactions
1 Transaction Belongs to 1 Account
However, I want to include bank accounts and transactions coming from different 3P sources. And while this relationship and the main fields are common across different sources, each source has a unique set of properties I want to keep.
To achieve this I decided to define these entities as abstract classes. This way, you can only instantiate concrete versions of these entities, each coming from a particular data source.
public abstract class Transaction : BaseEntity
{
public DataSource Source { get; private set; }
public decimal Amount { get; private set; }
public DateTime Date { get; private set; }
public string Name { get; private set; }
public BankAccount BankAccount { get; private set; }
public Guid BankAccountId { get; private set; }
...
}
public abstract class BankAccount : BaseEntity
{
public DataSource Source { get; private set; }
public string Name { get; private set; }
public Balance Balance { get; private set; }
public IEnumerable<Transaction> Transactions {get; private set;}
...
}
Here is a trimmed down example of the concrete implementations:
public class PlaidTransaction : Transaction
{
public string PlaidId { get; private set; }
private PlaidTransaction() : base() { }
public PlaidTransaction(decimal amount, DateTime date, string name, Guid bankAccountId, string plaidId) : base( amount, date, name, bankAccountId)
{
PlaidId = plaidId;
}
}
public class PlaidBankAccount : BankAccount
{
public string PlaidId { get; private set; }
...
}
I am using .Net Core with Entity Framework Core to persist my data and I managed to store my concrete classes all in the same table (TPH approach)
This works great and now all my entities live under the same table. So I can either query all Transactions or those of a certain type using LINQ's OfType<T> extension.
DbSet<Transaction> entities = _context.Set<Transaction>();
IEnumerable<PlaidTransaction> plaidTransactions = entities.OfType<PlaidTransaction>();
However, when I access my BankAccount field from my concrete Transaction I don't get the concrete instance. So something like this doesn't work.
plaidTransactions.Where((t) => t.BankAccount.PlaidId)
Instead I have to cast it:
plaidTransactions.Where((t) => (t.BankAccount as PlaidBankAccount).PlaidId)
What can I do to avoid casting everywhere? I feel there's a missing piece in my design that would make all my code easier. I was thinking of overriding the getters on my concrete classes but I don't know if I can return a derived class to a base class method. Maybe I should move to generics but 1) I still want to keep the fixed relationship between these entities and 2) how would EF Core handle this?

How to model this relationship efficiently

I have an Exercise table, each Exercise can be 1 of 5 Exercise Type (eg. cardio, timed activity, weights, combination of weights and timed, something else). Each of the different types stores the data in a different manner (eg. cardio is intensity and time, timed is just time in minutes, weights is sets x reps x weight, and something else could be something else).
So its a given that I have an Exercise table, but not sure how to model the Exercise Type and store the associated exercise data for each exercise type. Each Exercise will be of only one Exercise Type and each Exercise Type can belong to many Exercises.
I was leaning towards just an Exercise table and an Exercise Type table and have a many to one relationship, but I can't figure out how best to store each exercises data.
This is going to be modeled for Entity Framework 6 and MS SQL Server.
I think your scenario is good for Inheritance (using Table-per-Hierarchy), here is my suggested design:
public Exercise
{
public int ExerciseId {get;set;}
[ForeignKey("ExerciseBaseTypeId")]
public ExerciseBaseType ExerciseType {get;set;}
[Required]
public int ExerciseBaseTypeId {get;set;}
}
public ExerciseBaseType
{
public int BaseTypeId{get;set;}
public Link<Exercise> Exercises {get;set;}
//put other base properties that is common to all exercise types
}
public Cardio : ExerciseBaseType {
public string Intensity {get;set;}
public int Time {get;set;}
}
public Timed : ExerciseBaseType {
public int Duration {get;set;}
}
public Weight : ExerciseBaseType {
public int Sets {get;set;}
public int Weight {get;set;}
}
Here is your dbcontext file:
public class ExerciseDbContext : DbContext
{
public ExerciseDbContext()
: base("ExerciseDatabase"){ }
}
public DbSet<Exercise> Exercises { get; set; }
public DbSet<ExerciseBaseType> ExerciseTypes { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Exercise>()
.HasRequired(e => e.ExerciseBaseType)
.WithMany(ebt => ebt.Exercises)
.HasForeignKey(e.ExerciseBaseTypeId);
}
As an example, lets add a Timed Exercise and attach it to the exercise with id #1:
ExerciseDbContext db = new ExerciseDbContext();
var timedExercise = new Timed();
timedExercise.Duration = 60;
//set the other base properties
db.Exercises
.Single(e => e.ExerciseId = 1)
.ExerciseTypes.Add(timedExercise);
db.SaveChanges();
Does this make sense?

RavenDB Index on SubClasses

I am trying to create an indexes for ProviderProfileId, Email, and Address1
I have created queries that work, but not indexes. I know the inheriting from List for the collections might be part of the problem. List is a carry over from when I had to do a significant amount of XmlSerialization on much older projects, and became a habit in my modeling. I also noticed that in Raven the serialization is much cleaner that if AddressCollection were just List. Any thoughts?
Model is similar to
public class Customer {
public string Id {get;set}
public string Name {get;set;}
public AddressCollection {get;set;}
public SocialMediaAliasCollection {get;set;}
}
public class SocialMediaAliasCollection:List<SocialMedialProfile>{}
public class SocialMediaProfile{
public string ProviderProfileId {get;set;}
public string Email {get;set;}
}
public class AddressCollection:List<Address>{}
public class Address{
public string Address {get;set;}
public string City {get;set;}
public string State {get;set;}
public string Zip {get;set;}
}
I now answered it, basically I didn't know linq well enough. Makes sense once I figured it out. I was trying to make an index for a sub collection, in this case addresses. Not 100% this works, but it does compile and when I push the index to the server it does not blow up.
Map = collection => from item in collection where item.AddressCollection != null
from item2 in item.AddressCollection
select new {
item2.city
}

Nhibernate projection with child collection

Using NHibernate 2.1, I'm trying to project an entity and its child collection into a DTO. My entity looks like this..
public class Application
{
public int Id {get;set;}
public string Name {get;set;}
public List<ApplicationSetting> Settings {get;set;}
// A bunch of other properties that I don't want in the DTO
}
public class ApplicationSetting
{
public int Id {get;set;}
public string Name {get;set;}
public string Code {get;set;}
// A bunch of other properties that I don't want in the DTO
}
My DTO looks like this..
public ApplicationDto
{
public int Id {get;set;}
public string Name {get;set;}
public List<ApplicationSettingDto> Settings {get;set;}
}
public class ApplicationSettingDto
{
public int Id {get;set;}
public string Name {get;set;}
public string Code {get;set;}
}
My code to select JUST the Application and project it is this (using Nhibernate 2.1 and nhLambdaExtensions)
var applicationAlias = new Application();
var criteria = Session
.Add<Application>(a => a.Id == id);
int? Id = null;
string Name = null;
criteria
.SetProjection
(
Projections.Distinct(
Projections.ProjectionList()
.Add(LambdaProjection.Property<Application>(a => a.Id).As(() => Id))
.Add(LambdaProjection.Property<Application>(a => a.Name).As(() => Name))
)
);
criteria.SetResultTransformer(Transformers.AliasToBean(typeof(ApplicationDto)));
var contract = criteria.UniqueResult<ApplicationDto>();
My question is, how do I project just SOME of the properties from the ApplicationSettings entity to the ApplicationSettingsDto child collection?
I think you might need to do a MutiQuery and bring together the DTO parents and children yourself.

EF4 Code Only - Map Columns to Property Complex type

I have a table like this:
Name
Tree
Iron
Clay
Added
I want to map it to a model like this:
Name
Resources
Tree
Iron
Clay
Added
In makes sense to map it like this, when working with it in my program, but doing it that way in the databse would just make it more complex ... not would not add any useful things.
Is it possible with EF4 Code ONly?
public class Sample
{
public int Id { get; set;} // primary key required
public string Name {get;set;}
public DateTime Added{get;set;}
}
public class Resource
{
// no Id defined here
public string Tree{get;set;}
public string Iron { get;set;}
public string Clay { get;set;}
}
public class SampleDB : DbContext
{
//public DbSet<Resource> Resources { get; set; } // should not be there
public DbSet<Sample> Samples { get; set; }
}