Napisałem taką klasę:
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"
};
}
}
i
internal class DataContext : DbContext
{
public DbSet<Test> Tests { get; set; }
}
Po uruchomieniu kodu:
var db = new DataContext();
db.Tests.Add(new Test());
db.SaveChanges();
moje dane są zapisywane, ale tylko plik Id
. Nie mam żadnych tabel ani relacji odnoszących się do listy ciągów .
Co ja robię źle? Próbowałem też stworzyć Strings, virtual
ale to niczego nie zmieniło.
Dziękuję za pomoc.
c#
.net
entity-framework
Paweł
źródło
źródło
Test
encję. Stwórz więc nową jednostkę zId
właściwościami iMyString
właściwościami, a następnie zrób ich listę.Odpowiedzi:
Entity Framework nie obsługuje kolekcji typów pierwotnych. Możesz utworzyć encję (która zostanie zapisana w innej tabeli) lub wykonać przetwarzanie na łańcuchach, aby zapisać listę jako ciąg i zapełnić listę po zmaterializowaniu encji.
źródło
EF Core 2.1+:
Własność:
OnModelCreating:
źródło
Ta odpowiedź jest oparta na tych dostarczonych przez @Sasan i bloke @CAD .
Działa tylko z EF Core 2.1+ (niezgodnym z .NET Standard) (Newtonsoft
JsonConvert
)Korzystając z konfiguracji EF Core Fluent, serializujemy / deserializujemy
List
do / z formatu JSON.Dlaczego ten kod jest idealnym połączeniem wszystkiego, do czego możesz dążyć:
źródło
var result = await context.MyTable.Where(x => x.Strings.Contains("findme")).ToListAsync();
nic nie znajduję.Wiem, że to stare pytanie, a Paweł udzielił poprawnej odpowiedzi. Chciałem tylko pokazać przykład kodu pokazujący, jak przetwarzać ciągi znaków i uniknąć dodatkowej klasy dla listy typów pierwotnych.
źródło
,
(przecinek) w łańcuchach. Jeśli ciąg na liście zawiera jeden lub więcej,
(przecinek), ciąg jest dzielony na wiele ciągów.string.Join
przecinek powinien być otoczony przez cudzysłów (na sznurku), a nie apostrofów (dla char). Zobacz msdn.microsoft.com/en-us/library/57a79xd0(v=vs.110).aspxJSON.NET na ratunek.
Możesz serializować go do formatu JSON, aby zachować go w bazie danych, i deserializować go w celu ponownego utworzenia kolekcji .NET. Wydaje się, że działa lepiej, niż się spodziewałem w przypadku Entity Framework 6 i SQLite. Wiem, o co prosiłeś
List<string>
ale oto przykład jeszcze bardziej złożonej kolekcji, która działa dobrze.Oznaczyłem utrwaloną właściwość,
[Obsolete]
więc byłoby dla mnie bardzo oczywiste, że „to nie jest właściwość, której szukasz” w normalnym toku kodowania. Właściwość „real” jest oznaczona tagiem,[NotMapped]
więc Entity framework ją ignoruje.(niepowiązana styczna): Możesz zrobić to samo z bardziej złożonymi typami, ale musisz zadać sobie pytanie, czy sprawiłeś, że zapytanie o właściwości tego obiektu było dla siebie zbyt trudne? (tak, w moim przypadku).
źródło
Tylko dla uproszczenia -
Entity Framework nie obsługuje prymitywów. Możesz utworzyć klasę, aby ją opakować, lub dodać inną właściwość, aby sformatować listę jako ciąg:
źródło
Oczywiście Paweł udzielił właściwej odpowiedzi . Ale znalazłem w tym poście, że od EF 6+ można zapisywać prywatne nieruchomości. Więc wolałbym ten kod, ponieważ nie możesz zapisać ciągów znaków w niewłaściwy sposób.
źródło
StringsAsStrings
zostanie zaktualizowany tylko wtedy, gdyStrings
odniesienie zostanie zmienione, a jedyny przypadek w twoim przykładzie to czas przypisania. Dodanie lub usunięcie pozycji zStrings
listy po przypisaniu nie spowoduje zaktualizowaniaStringsAsStrings
zmiennej bazowej. Właściwym sposobem realizacji tego byłoby wyeksponowanieStringsAsStrings
jako widokuStrings
listy, a nie odwrotnie. Połącz wartości ze sobą wget
akcesoriumStringsAsStrings
właściwości i podziel je wset
akcesorium.Niewielkie szczypanie @Mathieu Viales „s odpowiedź , oto fragment kompatybilny NET Standardowy użyciu nowego System.Text.Json serializatora eliminując w ten sposób zależność od Newtonsoft.Json.
Zauważ, że chociaż drugi argument w obu
Serialize()
iDeserialize()
zazwyczaj jest opcjonalny, pojawi się błąd:Jawne ustawienie wartości domyślnej (null) dla każdego usuwa to.
źródło
Możesz użyć tego
ScalarCollection
kontenera, który ogranicza tablicę i zapewnia pewne opcje manipulacji ( Gist ):Stosowanie:
Kod:
źródło
NET462
odpowiednie środowisko lub dodajesz je do niego.