I have 2 classes i'm trying to map namely
1) Entity
2) DTO
I'm trying to map Entity.Foo to DTO.Child.Foo
Obviously the below will not work, how do I achieve this. I need to create a new instance of Child and then attach that to the Mapper and then set the Foo property but my AutoMapper skills are not that good!
Mapper.CreateMap<Entity, DTO>()
.ForMember("Child.Foo", m => m.MapFrom(entity => entity.Foo))
Mapper.CreateMap<Entity, DTO>()
.ForMember(d => d.Foo,
o => o.ResolveUsing(s => new DTO.Child { Foo = s.Foo }))
// comment
Related
I have just done the following (EF Core 3.1):
var aaa = context
.Table1
.Include(t => t.Table2.Table3.Table4);
.Include(t => t.Table2.Table3.Table5);
and I have in my variabe aaa the elements of Table1 and the ones in all subsequent child tables. I thought a .ThenInclude was necessary in these cases. I thought this had to be done the following way:
var aaa = context
.Table1
.Include(t => t.Table2);
.ThenInclude(t2 => t2.Table3)
.ThenInclude(t3 => t3.Table4)
.Include(t => t.Table2);
.ThenInclude(t2 => t2.Table3)
.ThenInclude(t3 => t3.Table5)
Is ThenInclude not necessary? What is it for, then?
Using EF Core 3 and Mapster I would like to map from a flat dto object to an object with a related sub-object.
i.e.
_ = TypeAdapterConfig<NoteVM, Note>.NewConfig()
.Map(d => d.Detail, s => s.Description)
.Map(d => d.Id, s => s.NoteId)
.Map(d => d.NoteTypeObject, s => s.NoteTypeString)
.IgnoreNullValues(true);
Where NoteTypeObject is an existing record on a table.
So in the mapping the NoteType object has to be retrieved from the db and attached to the Note record before the Note record is saved.
Can this be done in the config section or does this need to be done after the mapping but before the Note object is saved to the DB?
_ = TypeAdapterConfig<NoteVM, Note>.NewConfig()
.Map(d => d.Detail, s => s.Description)
.Map(d => d.Id, s => s.NoteId)
//get existing Id
.Map(d => d.NoteTypeObjectId, s => GetNoteTypeId(s.NoteTypeString))//lookup
.IgnoreNullValues(true);
If you are able to add a reference ID instead of object reference you can do something like the above.
I'm exploring the different possibilities on how to implement a generic DAO using the latest Slick 3.1.1 to boost productivity and yes there is need for it because basing the service layer of my Play Web application on TableQuery alone leads to a lot of boilerplate code. One of the methods I'd like to feature in my generic DAO implementation is the findByExample, possible in JPA with the help of the Criteria API. In my case, I'm using the Slick Code Generator to generate the model classes from a sql script.
I need the following to be able to dynamically access the attribute names, taken from Scala. Get field names list from case class:
import scala.reflect.runtime.universe._
def classAccessors[T: TypeTag]: List[MethodSymbol] = typeOf[T].members.collect {
case m: MethodSymbol if m.isCaseAccessor => m
}.toList
A draft implementation for findByExample would be:
def findByExample[T, R](example: R) : Future[Seq[R]] = {
var qt = TableQuery[T].result
val accessors = classAccessors[R]
(0 until example.productArity).map { i =>
example.productElement(i) match {
case None => // ignore
case 0 => // ignore
// ... some more default values => // ignore
// handle a populated case
case Some(x) => {
val columnName = accessors(i)
qt = qt.filter(_.columnByName(columnName) == x)
}
}
}
qt.result
}
But this doesn't work because I need better Scala Kungfu. T is the entity table type and R is the row type that is generated as a case class and therefore a valid Scala Product type.
The first problem in that code is that would be too inefficient because instead of doing e.g.
qt.filter(_.firstName === "Juan" && _.streetName === "Rosedale Ave." && _.streetNumber === 5)
is doing:
// find all
var qt = TableQuery[T].result
// then filter by each column at the time
qt = qt.filter(_.firstName === "Juan")
qt = qt.filter(_.streetName === "Rosedale Ave.")
qt = qt.filter(_.streetNumber === 5)
Second I can't see how to dynamically access the column name in the filter method i.e.
qt.filter(_.firstName == "Juan")
I need to instead have
qt.filter(_.columnByName("firstName") == "Juan")
but apparently there is no such possibility while using the filter function?
Probably the best ways to implement filters and sorting by dynamically provided column names would be either plain SQL or extending the code generator to generate extension methods, something like this:
implicit class DynamicPersonQueries[C[_]](q: Query[PersonTable, PersonRow, C]){
def dynamicFilter( column: String, value: String ) = column {
case "firstName" => q.filter(_.firstName === value)
case "streetNumber" => q.filter(_.streetNumber === value.toInt)
...
}
}
You might have to fiddle with the types a bit to get it to compile (and ideally update this post afterwards :)).
You can then filter by all the provided values like this:
val examples: Map[String, String] = ...
val t = TableQuery[PersonTable]
val query = examples.foldLeft(t){case (t,(column, value)) => t.dynamicFilter(column, value)
query.result
Extending the code generator is explained here: http://slick.lightbend.com/doc/3.1.1/code-generation.html#customization
After further researching found the following blog post Repository Pattern / Generic DAO Implementation.
There they declare and implement a generic filter method that works for any Model Entity type and therefore it is in my view a valid functional replacement to the more JPA findByExample.
i.e.
T <: Table[E] with IdentifyableTable[PK]
E <: Entity[PK]
PK: BaseColumnType
def filter[C <: Rep[_]](expr: T => C)(implicit wt: CanBeQueryCondition[C]) : Query[T, E, Seq] = tableQuery.filter(expr)
How can I write deleteWhere clause in squeryl for entity with composite id?
val list: List[CompositeKey2[Long, Date]] = existing.map(x => x.id).toList
Schema.entities.deleteWhere(q => q.id in list)
Error:(82, 49) value in is not a member of org.squeryl.dsl.CompositeKey2[Long,java.util.Date]
Schema.entities.deleteWhere(q => q.id in list)
^
With a CompositeKey, the id method doesn't map directly to a column, so it isn't useful in an in clause. You'll have to structure your where to reference each column that makes up the private key individually. Without knowing the columns involved it's tough to be more specific, but something like
deleteWhere(q => existing.map(e => q.id1 === e.id1 and q.id2 === e.id2).reduce(_ or _))
Is there an elegant way in to update an already existing value in a Map?
This looks too scary:
val a = map.get ( something )
if ( a != null ) // case .. excuse my old language
a.apply( updateFunction )
else
map.put ( something, default )
Most of the time you can insert something that can be updated when it's created (e.g. if it's a count, you put 0 in it and then update to 1 instead of just putting 1 in to start). In that case,
map.getOrElseUpdate(something, default).apply(updateFunction)
In the rare cases where you can't organize things this way,
map(something) = map.get(something).map(updateFunction).getOrElse(default)
(but you have to refer to something twice).
This is what I usually write... not sure if there are better solutions.
map.get(key) match {
case None => map.put(key, defaultValue)
case Some(v) => map(key) = updatedValue
}
In fact update and put are the same for mutable map, but I usually use update on existing entries and put for new ones, just for readability.
Another thing is that if you can figure out what the ultimate value is without checking the existence of the key, you can simply write map(key) = value, at it automatically creates/replaces the entry.
Finally, statements like map(key) += 1 actually works in Map (this is generally true for collections with update function), and so do many simple numeric operations.\
To solve double put, use mutable object instead of immutable values:
class ValueStore(var value: ValueType)
val map = new Map[KeyType, ValueStore]
...
map.get(key) match {
case None => map.put(key, new ValueStore(defaultValue))
case Some(v) => v.value = updatedValue
}
As I mentioned in the comment, the underlying structure of HashMap is HashTable, which actually use this mutable wrapper class approach. HashMap is a nicer wrap-up class but you sometimes just have to do duplicated computation.
me stupid, you are (quite) right:
map.get(key) match {
case None => map.put(key, defaultValue)
case Some(v) => v.apply(updateFunction) // changes state of value
}
tsts
thanks