valid - summary returns c#
Obtención de salida inapropiada con la combinación izquierda (2)
Estoy tratando de obtener una lista de variantes y para cada una de estas variantes obtener todas las subvariants list
independientemente de dónde caen las subvarianzas para una Test say 100
particular Test say 100
Estos son datos de muestra:
Id TestId SourceSubVariantId TargetSubVariantId DiffPerc
114 100 66 67 100.00
115 100 67 68 100.00
116 100 70 71 99.99
Tengo 3 subvariants para las variantes 1 :
Id=66,Name=Abc
Id=68,Name=Pqr
Id=69,Name=xyz
Tengo 3 subvariants para Variants 2 :
Id=70,Name=lmn
Id=71,Name=xxx
Id=72,Name=hhh
Pero note que en mi salida en estoy obteniendo todas las Id as 0
para la subvariants list
de Variants 2
en Variant1 CustomSubvariantList
:
Modelo de datos:
public class Variants
{
public int Id { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public virtual ICollection<SubVariants> SubVariants { get; set; }
}
public class SubVariants
{
public int Id { get; set; }
public int VariantId { get; set; }
public string Name { get; set; }
public virtual Variants Variants { get; set; }
public virtual ICollection<TestOperation> TestOperation { get; set; }
public virtual ICollection<TestOperation> TestOperation1 { get; set; }
}
public class TestOperation
{
public int Id { get; set; }
public Nullable<int> TestId { get; set; }
public int SourceSubVariantId { get; set; }
public int TargetSubVariantId { get; set; }
public decimal DiffPerc { get; set; }
public virtual SubVariants SubVariants { get; set; }
public virtual SubVariants SubVariants1 { get; set; }
public virtual Test Test { get; set; }
}
Consulta:
int testId=100;
var query =
from v in context.Variants
where v.Type == "Add"
select new
{
ParentVariant = v.Name,
Type = v.Method,
CustomSubvariantList =
(
from svName in context.SubVariants.Select(sv => sv.Name).Distinct()
join x in
(
from sv in v.SubVariants
from to in sv.TestOperation
where to.TestId == testId
orderby sv.Id
select new
{
sv.Name,
to.DiffPerc,
SourceId = (int?)to.SubVariants.Id,
TargetID=(int?)to.SubVariants1.Id
}
)
on svName equals x.Name into g
from x in g.DefaultIfEmpty()
orderby x.SourceId
select new
{
SourceId=x.SourceId ?? 0,
TargetId=x.TargetID ?? 0,
Name = svName,
DiffPerc = x.DiffPerc
}
).ToList()
};
Actualización: en base a los comentarios, esta es la muestra de entradas y la salida esperada:
Caso 1 : cuando el nombre de los subvarios es diferente en todas las variantes principales
Variantes:
Id Name Type CategoryId
11 Variant1 Add 1
12 Variant2 Add 1
13 Variant3 Add 1
14 Variant4 Add 1
Subvariantes:
Id VariantId Name
66 11 Abc
67 11 PQR
68 11 Xyz
70 12 lmn
71 12 xxx
72 12 hhh
Operación de prueba:
Id TestId SourceSubVariantId TargetSubVariantId DiffPerc
114 100 66 67 10.00
115 100 67 68 20.00
114 100 70 71 40.00
115 100 71 72 50.00
Caso 2 : cuando los nombres de los subvariantes son iguales en todas las variantes de los padres
Subvariantes:
Id VariantId Name
66 11 Abc
67 11 PQR
68 11 Xyz
70 12 Abc
71 12 PQR
72 12 Xyz
Esta es una "variante" de su consulta. Extrae todas las SubVariants
por Variant(s)
ordenadas tal como están en la tabla Subvarianzas (por su ID de identidad de servidor Sql), independientemente de la TestOperation
de TestOperation
involucrada y evite duplicados como sus resultados esperados.
Lamentablemente, no es posible tener siempre todas las subvarianzas designadas como subvariantes de origen y tartget, ya que esta información depende de la operación de prueba, de hecho, Testop decide si una subvariante es "fuente" o "destino". Por lo tanto, si algunas subvarianzas no están incluidas en los registros / entidad de las operaciones de prueba, entonces no pueden aparecer como origen o destino. Una solución alternativa podría ser adjuntar, junto a la propiedad "Nombre" del tipo anónimo devuelto, también "Id SubVar"
Agregué 2 DTO porque el marco de la entidad no permite el uso de los distinct().ToList()
para conservar el orden y aplicar una regla distinta personalizada, así que agregué un paso más para pasar de Vincular a EF en Vincular a objeto a través de objetos dto y en De esta manera se posibilita la aplicación de la regla personalizada distinta.
public class CustomerVariantDTO
{
public String Type;
public String ParentVariant;
public IEnumerable<CustomerSubVariantDTO> CustomSubvariantList;
}
public class CustomerSubVariantDTO
{
public int? VariantId;
public int? SubVariantId;
public int? SourceId;
public int? TargetId;
public String Name;
public Decimal? DiffPerc;
}
sealed class CustomerSubVariantDTOComparer : IEqualityComparer<CustomerSubVariantDTO>
{
public int GetHashCode(CustomerSubVariantDTO obj)
{
return 0;
}
public bool Equals(CustomerSubVariantDTO x, CustomerSubVariantDTO y)
{
return x.SourceId == y.SourceId &&
x.TargetId == y.TargetId &&
x.Name == y.Name &&
x.DiffPerc == y.DiffPerc;
}
}
public void DoTestOfCustomerVariantDTO()
{
int testId = 1;
using (var context = new VariantsEntities())
{
var query =
(from v in context.Variants
where v.Type == "Add"
select new CustomerVariantDTO
{
ParentVariant = v.Name,
Type = v.Type,
CustomSubvariantList =
(
from sv in context.SubVariants.Select(sv => sv)
join x in
(
from svparent in v.SubVariants
from to in svparent.TestOperation
where to.TestId == testId
select new
{
svparent.Name,
to.DiffPerc,
SourceId = (int?)to.SubVariants.Id ?? 0,
TargetId = (int?)to.SubVariants1.Id ?? 0
}
)
on sv.Name equals x.Name into g
from x in g.DefaultIfEmpty()
select new CustomerSubVariantDTO{
VariantId = sv.VariantId,
SubVariantId = sv.Id,
SourceId = (int?)x.SourceId ?? sv.TestOperation.Select(to => to.SourceSubVariantId).FirstOrDefault(),
TargetId = (int?)x.TargetId ?? sv.TestOperation.Select(to => to.TargetSubVariantId).FirstOrDefault(),
Name = sv.Name,
DiffPerc = x.DiffPerc
}
).OrderBy(csv => new { csv.VariantId, csv.SubVariantId })
}).ToList();
var listCustomVariants =
query.Select(v => new{
Type = v.Type,
ParentVariant = v.ParentVariant,
CustomSubvariantList = v.CustomSubvariantList.Distinct(new CustomerSubVariantDTOComparer()).ToList()
});
foreach (var item in listCustomVariants){
Console.WriteLine($"Type: {item.Type} - ParentVariant: {item.ParentVariant} ");
foreach (var csubvar in item.CustomSubvariantList)
Console.WriteLine($"SourceId: {csubvar.SourceId} - TargetiId: {csubvar.TargetId} - NAme: {csubvar.Name} - DiffPerc: {csubvar.DiffPerc} ");
}
}
}
Tuvimos algunas discusiones en el chat hasta que entendí lo que quieres.
este es el codigo
class Program
{
static void Main(string[] args)
{
VariantsEntities db=new VariantsEntities();
var queryResult = db.Variants.AsEnumerable().Select(x => new PageViewModel
{
ParentVariant = x.Name,
Type = x.Type,
CustomSubvariantList = GetCustomSubVariants(x.Id,db).ToList()
}).ToList();
var jsonObj = JsonConvert.SerializeObject(queryResult);
Console.WriteLine(jsonObj);
Console.ReadKey();
}
private static IEnumerable<Customsubvariantlist> GetCustomSubVariants(int variantId, VariantsEntities db)
{
var subVariants = db.SubVariants.ToList();
foreach (var subVariant in subVariants)
{
var obj=new Customsubvariantlist();
obj.Name = subVariant.Name;
var testOpTarget = db.TestOperations
.FirstOrDefault(x => x.TargetSubVariantId == subVariant.Id);
var testOpSource = db.TestOperations
.FirstOrDefault(x => x.SourceSubVariantId == subVariant.Id);
if (subVariant.VariantId == variantId)
{
obj.Value = testOpTarget == null ?
testOpSource?.SourceValue : testOpTarget?.TargetValue;
obj.DiffPerc = testOpTarget?.DiffPerc;
}
else
{
obj.Value = null;
obj.DiffPerc = null;
}
yield return obj;
}
}
}
solo necesita reemplazar el nombre DbContext y probarlo.
este es el resultado:
[
{
"ParentVariant": "Variant1",
"Type": "Add",
"CustomSubvariantList": [
{
"Name": "Abc",
"Value": 200,
"DiffPerc": null
},
{
"Name": "Pqr",
"Value": 300,
"DiffPerc": 100.0
},
{
"Name": "xyz",
"Value": 500,
"DiffPerc": 200.0
},
{
"Name": "lmn",
"Value": null,
"DiffPerc": null
},
{
"Name": "xxx",
"Value": null,
"DiffPerc": null
},
{
"Name": "hhh",
"Value": null,
"DiffPerc": null
}
]
},
{
"ParentVariant": "Variant2",
"Type": "Add",
"CustomSubvariantList": [
{
"Name": "Abc",
"Value": null,
"DiffPerc": null
},
{
"Name": "Pqr",
"Value": null,
"DiffPerc": null
},
{
"Name": "xyz",
"Value": null,
"DiffPerc": null
},
{
"Name": "lmn",
"Value": 1000,
"DiffPerc": null
},
{
"Name": "xxx",
"Value": 2000,
"DiffPerc": 1000.0
},
{
"Name": "hhh",
"Value": 4000,
"DiffPerc": 2000.0
}
]
}
]
Desde here puedes descargar el proyecto de muestra. Este proyecto se realizó con la base de datos de muestra que me envió, también lo es la Base de datos primero y es posible que algunos accesorios o tablas tengan un nombre diferente, verifique esto antes de mover el código en su proyecto.
Básicamente lo que hice:
creado un nuevo proyecto de aplicación de consola
Obtuve el modelo de su objeto json (copié el objeto json y lo pase en una clase, usando (menú vs) Edición -> Especial pasado -> JSON anterior como clases.
Como desea que todos los
SubVariants
para cadaVarian
, creé un método separado para manejar las reglas que tenía para crear elCustomSubVariantList
. En este método, repito iterativamente todas las subvariedades y creé objetos basados en sus condiciones.
Actualización: su solución en una consulta:
static void Main(string[] args)
{
VariantsEntities db = new VariantsEntities();
var result = from x in db.Variants
select new PageViewModel
{
ParentVariant = x.Name,
Type = x.Type,
CustomSubvariantList = (from z in db.SubVariants
let testOpTarget=z.TestOperations1
.FirstOrDefault(q=>q.TargetSubVariantId==z.Id)
let testOpSource=z.TestOperations
.FirstOrDefault(q=>q.SourceSubVariantId==z.Id)
select new Customsubvariantlist
{
Name = z.Name,
Value = x.Id==z.VariantId?
testOpTarget.TargetValue??
testOpSource.SourceValue:null,
DiffPerc = x.Id==z.VariantId?
testOpTarget.DiffPerc:null
}).ToList()
};
var json = JsonConvert.SerializeObject(result.ToList());
Console.WriteLine(json);
Console.ReadKey();
}
Esta consulta produce el mismo resultado que el método anterior. Por favor déjame saber si es lo que necesitas !!
Actualización: esta es la consulta para el caso 2
var result = from x in db.Variants
select new PageViewModel
{
ParentVariant = x.Name,
Type = x.Type,
CustomSubvariantList = (from z in db.SubVariants.GroupBy(g => g.Name)
.Select(g => g.FirstOrDefault(d => d.VariantId == x.Id) ?? g.FirstOrDefault())
let testOpTarget = z.TestOperations1
.FirstOrDefault(q => q.TargetSubVariantId == z.Id)
let testOpSource = z.TestOperations
.FirstOrDefault(q => q.SourceSubVariantId == z.Id)
select new Customsubvariantlist
{
Name = z.Name,
SubVariantId = z.Id,
CombineName =(z.TestOperations.Any() || z.TestOperations1.Any())?
testOpTarget.TargetValue.HasValue?
testOpTarget.SubVariant.Name+" to "+testOpTarget.SubVariant1.Name : null: "Undefined",
Value = x.Id == z.VariantId
? testOpTarget.TargetValue ??
testOpSource.SourceValue
: null,
DiffPerc = x.Id == z.VariantId
? testOpTarget.DiffPerc
: null
}).OrderBy(k => k.SubVariantId).ToList()
};