当第二个映射函数向Mapstruct明确给出映射信息时,为什么不自动生成映射代码?
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Data.Entity.Migrations;
using System.Linq;
namespace TestApp
{
internal class Program
{
public static void Main(string[] p)
{
DeleteData();
CreateRecipes();
using (var db = new DbModel())
{
var recipe1 = (from x in db.recipeDS.OfType<ScrubRecipe>()
.Include(x => x.steps)
select x).FirstOrDefault();
//var recipe2 = (from x in db.recipeDS.OfType<ScrubRecipe>()
// .Include(x => x.steps.OfType<ScrubStep>().Select(y => y.outputList))
// select x).FirstOrDefault();
}
}
private static void DeleteData()
{
using (var db = new DbModel())
{
db.Database.ExecuteSqlCommand("DELETE FROM [StepOutputs]");
db.Database.ExecuteSqlCommand("DELETE FROM [RecipeSteps]");
db.Database.ExecuteSqlCommand("DELETE FROM [Recipes]");
}
}
private static void CreateRecipes()
{
// Output to be saved.
var stepOutput = new StepOutput();
// Create a Recipe
var scrubRecipe = new ScrubRecipe
{ steps = { new ScrubStep { outputList = { stepOutput } } } };
// Create a Recipe
var coatRecipe = new CoatRecipe
{ steps = { new CoatStep { outputList = { stepOutput } } } };
// Save the Recipes
using (var db = new DbModel())
{
db.scrubRecipeDS.AddOrUpdate(scrubRecipe);
db.coatRecipeDS.AddOrUpdate(coatRecipe);
db.SaveChanges();
}
}
}
public abstract class Recipe
{
[Key]
public int ID { get; set; }
public List<RecipeStep> steps { get; set; } = new List<RecipeStep>();
}
public class CoatRecipe : Recipe { }
public class ScrubRecipe : Recipe { }
public abstract class RecipeStep
{
[Key]
public int ID { get; set; }
public virtual Recipe recipe { get; set; }
}
public class CoatStep : RecipeStep
{
public List<StepOutput> outputList { get; set; } = new List<StepOutput>();
}
public class StepOutput
{
[Key]
public int ID { get; set; }
public virtual RecipeStep recipeStep { get; set; }
}
public class ScrubStep : CoatStep
{
public int value { get; set; }
}
public class DbModel : DbContext
{
public DbModel()
: base("name=DbModelConn")
{
Database.SetInitializer(new CreateDatabaseIfNotExists<DbModel>());
}
public virtual DbSet<Recipe> recipeDS { get; set; }
public DbSet<RecipeStep> recipeStepDS { get; set; }
public DbSet<StepOutput> stepOutputDS { get; set; }
public virtual DbSet<ScrubRecipe> scrubRecipeDS { get; set; }
public virtual DbSet<ScrubStep> scrubRecipeStepDS { get; set; }
public virtual DbSet<CoatRecipe> coatRecipeDS { get; set; }
public virtual DbSet<CoatStep> coatRecipeStepsDS { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ScrubStep>()
.HasMany(x => x.outputList)
.WithRequired(x => (ScrubStep)x.recipeStep);
}
}
}
Flat Composed
---- --------
- String a - String a
- Sub
- String b - String b
- String c - String c
清晰用法:
@Mapper(uses = SubToFlatMapper.class)
public interface ComposedToFlatMapper {
Flat map(Composed c); // Unmapped target properties: "b, c".
// Not OK because Sub mapping is defined in
// SubToFlatMapper and is used here :(
}
@Mapper
public interface SubToFlatMapper {
Flat map(Sub s); // Unmapped target properties: "a".
// (OK because 'a' is not in Sub)
}
Composed composed = new Composed();
Sub sub = new Sub();
composed.setA("A");
composed.setSub(sub);
sub.setB("B");
sub.setC("C");
Flat flat = ComposedToFlatMapper.INSTANCE.map(composed);
// flat.getA() is "A", OK!
// flat.getB() is null, unexpected, should be "B"
// flat.getC() also null, should be "C".
和"B"
未映射到"C"
,因为生成代码不会为此创建方法。
我以为我已经向生成器提供了所需的映射信息。它应该在看到flat
方法时在ComposedToFlatMapperImpl
内生成。
修改:
之前我没有提到过,但在最初的问题中,我也可以使用Flat map(Sub s)
- 更灵活的方法。
现在,假设有一个新的update
类型。 :
Sub2
@Mapper(uses = {SubToFlatMapper.class, Sub2ToFlatMapper.class})
public interface ComposedToFlatMapper {
Flat map(Composed c);
void update(Composed source, @MappingTarget Flat target);
}
@Mapper
public interface SubToFlatMapper {
Flat map(Sub s);
void update(Sub source, @MappingTarget Flat target);
}
@Mapper
public interface Sub2ToFlatMapper {
Flat map(Sub2 s);
void update(Sub2 source, @MappingTarget Flat target);
}
由于Flat Composed
---- --------
- String a - String a
- Sub
- String b - String b
- String c - String c
- Sub2
- String d
- String e
没有Flat
引用,因此请忽略它。无需生成映射代码。
答案 0 :(得分:1)
您可以简单地展平嵌套的源结构,如下所示:
@Mapper
public interface ComposedToFlatMapper {
@Mapping(target="b", source="sub.b")
@Mapping(target="c", source="sub.c")
Flat map(Composed c);
}