Escribí tal clase:
class Test
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public List<String> Strings { get; set; }
public Test()
{
Strings = new List<string>
{
"test",
"test2",
"test3",
"test4"
};
}
}
y
internal class DataContext : DbContext
{
public DbSet<Test> Tests { get; set; }
}
Después de ejecutar el código:
var db = new DataContext();
db.Tests.Add(new Test());
db.SaveChanges();
mis datos se están guardando pero solo el Id
. No tengo tablas ni relaciones que se apliquen a la lista de cadenas .
¿Qué estoy haciendo mal? Intenté también hacer Strings virtual
pero no cambió nada.
Gracias por tu ayuda.
c#
.net
entity-framework
Pablo
fuente
fuente
Test
entidad. Así que crea una nueva entidad conId
propiedad yMyString
propiedad, luego haz una lista de eso.Respuestas:
Entity Framework no admite colecciones de tipos primitivos. Puede crear una entidad (que se guardará en una tabla diferente) o realizar algún procesamiento de cadena para guardar su lista como una cadena y completar la lista después de que la entidad se materialice.
fuente
EF Core 2.1+:
Propiedad:
OnModelCreating:
fuente
Esta respuesta se basa en las proporcionadas por @Sasan y @CAD bloke .
Funciona solo con EF Core 2.1+ (no compatible con .NET Standard) (Newtonsoft
JsonConvert
)Usando la configuración fluida de EF Core, serializamos / deserializamos el
List
a / desde JSON.Por qué este código es la combinación perfecta de todo lo que puede esforzarse:
fuente
var result = await context.MyTable.Where(x => x.Strings.Contains("findme")).ToListAsync();
no encuentra nada.Sé que esta es una pregunta antigua, y Pawel ha dado la respuesta correcta , solo quería mostrar un ejemplo de código de cómo hacer un procesamiento de cadenas y evitar una clase adicional para la lista de un tipo primitivo.
fuente
,
(coma) en cadenas. Si una cadena de la lista contiene una o más,
(coma), la cadena se divide en varias cadenas.string.Join
la coma debe ser rodeado por comillas dobles (por una cadena), y no comillas simples (para un char). Ver msdn.microsoft.com/en-us/library/57a79xd0(v=vs.110).aspxJSON.NET al rescate.
Lo serializa en JSON para persistir en la base de datos y lo deserializa para reconstituir la colección .NET. Esto parece funcionar mejor de lo que esperaba con Entity Framework 6 y SQLite. Sé que lo pidió,
List<string>
pero aquí hay un ejemplo de una colección aún más compleja que funciona bien.Etiqueté la propiedad persistente con
[Obsolete]
para que fuera muy obvio para mí que "esta no es la propiedad que está buscando" en el curso normal de la codificación. La propiedad "real" está etiquetada con,[NotMapped]
por lo que Entity framework la ignora.(tangente no relacionada): podría hacer lo mismo con tipos más complejos, pero debe preguntarse si hizo que consultar las propiedades de ese objeto sea demasiado difícil para usted. (sí, en mi caso).
fuente
Solo para simplificar:
Entity framework no admite primitivas. Puede crear una clase para envolverla o agregar otra propiedad para formatear la lista como una cadena:
fuente
Por supuesto, Pawel ha dado la respuesta correcta . Pero encontré en esta publicación que desde EF 6+ es posible guardar propiedades privadas. Así que preferiría este código, porque no puede guardar las cadenas de forma incorrecta.
fuente
StringsAsStrings
solo se actualizará cuando se cambie laStrings
referencia , y la única vez en su ejemplo que ocurre es en la asignación. Agregar o eliminar elementos de suStrings
lista después de la asignación no actualizará laStringsAsStrings
variable de respaldo. La forma correcta de implementar esto sería exponerStringsAsStrings
como una vista de laStrings
lista, en lugar de al revés. Una los valores en elget
descriptor de acceso de laStringsAsStrings
propiedad y divídalos en elset
descriptor de acceso.Modificando ligeramente la respuesta de @Mathieu Viales , aquí hay un fragmento de código compatible con .NET Standard que utiliza el nuevo serializador System.Text.Json eliminando así la dependencia de Newtonsoft.Json.
Tenga en cuenta que si bien el segundo argumento en ambos
Serialize()
yDeserialize()
suele ser opcional, obtendrá un error:Establecer explícitamente eso en el valor predeterminado (nulo) para cada uno aclara eso.
fuente
Puede usar este
ScalarCollection
contenedor que limita una matriz y proporciona algunas opciones de manipulación ( Gist ):Uso:
Código:
fuente
NET462
con el entorno apropiado o agregarlo.