Если во время проверки не появляется ошибка MySQL, убедитесь, что вы правильно создали таблицу базы данных. Это случилось со мной. Ищите любые нежелательные запятые или цитаты.
Entity Framework не поддерживает коллекции примитивных типов. Вы можете создать объект (который будет сохранен в другой таблице) или выполнить некоторую строковую обработку, чтобы сохранить ваш список в виде строки и заполнить список после того, как объект материализуется.
Просто для упрощения -
Структура Entity не поддерживает примитивы. Вы либо создаете класс для его переноса, либо добавляете другое свойство для форматирования списка в виде строки:
public ICollection<string> List { get; set; }
public string ListString
{
get { return string.Join(",", List); }
set { List = value.Split(',').ToList(); }
}
Сериализуйте его в JSON для сохранения в базе данных и Deserialize для восстановления коллекции .NET. Кажется, что это работает лучше, чем я ожидал от него с Entity Framework 6 & amp; SQLite. Я знаю, что вы попросили List<string>
, но вот пример еще более сложной коллекции, которая работает очень хорошо.
Я отметил сохраненное свойство с помощью [Obsolete]
, поэтому было бы очень очевидно, что «это не является тем свойством, которое вы ищете "в процессе обычной кодировки. Свойство «real» помечено значком [NotMapped]
, поэтому инфраструктура Entity игнорирует его.
(несвязанный тангенс): вы можете сделать то же самое с более сложными типами, но вам нужно спросить себя, вы просто попросили свойства объекта слишком сложны для вас? (да, в моем случае).
using Newtonsoft.Json;
....
[NotMapped]
public Dictionary<string, string> MetaData { get; set; } = new Dictionary<string, string>();
/// <summary> <see cref="MetaData"/> for database persistence. </summary>
[Obsolete("Only for Persistence by EntityFramework")]
public string MetaDataJsonForDb
{
get
{
return MetaData == null || !MetaData.Any()
? null
: JsonConvert.SerializeObject(MetaData);
}
set
{
if (string.IsNullOrWhiteSpace(value))
MetaData.Clear();
else
MetaData = JsonConvert.DeserializeObject<Dictionary<string, string>>(value);
}
}
Конечно Павел дал правильный ответ . Но я нашел в этом сообщении , что с EF 6+ можно сохранить частные свойства. Поэтому я бы предпочел этот код, потому что вы не можете сохранить строки неправильно.
public class Test
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Column]
[Required]
private String StringsAsStrings { get; set; }
public List<String> Strings
{
get { return StringsAsStrings.Split(',').ToList(); }
set
{
StringsAsStrings = String.Join(",", value);
}
}
public Test()
{
Strings = new List<string>
{
"test",
"test2",
"test3",
"test4"
};
}
}
Вы можете использовать этот контейнер ScalarCollection
, который ограничивает массив и предоставляет некоторые параметры манипуляции ( Gist ):
Использование:
public class Person
{
public int Id { get; set; }
//will be stored in database as single string.
public SaclarStringCollection Phones { get; set; } = new ScalarStringCollection();
}
Код:
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
namespace System.Collections.Specialized
{
#if NET462
[ComplexType]
#endif
public abstract class ScalarCollectionBase<T> :
#if NET462
Collection<T>,
#else
ObservableCollection<T>
#endif
{
public virtual string Separator { get; } = "\n";
public virtual string ReplacementChar { get; } = " ";
public ScalarCollectionBase(params T[] values)
{
if (values != null)
foreach (var item in Items)
Items.Add(item);
}
#if NET462
[Browsable(false)]
#endif
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("Not to be used directly by user, use Items property instead.")]
public string Data
{
get
{
var data = Items.Select(item => Serialize(item)
.Replace(Separator, ReplacementChar.ToString()));
return string.Join(Separator, data.Where(s => s?.Length > 0));
}
set
{
Items.Clear();
if (string.IsNullOrWhiteSpace(value))
return;
foreach (var item in value
.Split(new[] { Separator },
StringSplitOptions.RemoveEmptyEntries).Select(item => Deserialize(item)))
Items.Add(item);
}
}
public void AddRange(params T[] items)
{
if (items != null)
foreach (var item in items)
Add(item);
}
protected abstract string Serialize(T item);
protected abstract T Deserialize(string item);
}
public class ScalarStringCollection : ScalarCollectionBase<string>
{
protected override string Deserialize(string item) => item;
protected override string Serialize(string item) => item;
}
public class ScalarCollection<T> : ScalarCollectionBase<T>
where T : IConvertible
{
protected override T Deserialize(string item) =>
(T)Convert.ChangeType(item, typeof(T));
protected override string Serialize(T item) => Convert.ToString(item);
}
}