У меня возникли проблемы с Entity Framework в .NET Framework. Мое приложение спроектировано следующим образом:
У меня есть класс, который наследуется от DbContext, и у меня есть это свойство:
public DbSet Users { get; set; }
// ...other properties
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity()
.HasRequired(umz => umz.User)
.WithMany(u => u.ManageableZones)
.HasForeignKey(umz => umz.Username)
.WillCascadeOnDelete(false);
}
Мой пользователь модель - это примерно так:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[Required]
[MaxLength(128)]
[Column("USERNAME")]
public string Username { get; set; } = string.Empty;
public virtual ICollection ManageableZones { get; set; }
public User()
{
ManageableZones = new HashSet();
}
Как вы можете видеть, у меня есть свойство Manageblezones , то есть таблица, с которой я хочу связать, с отношениями 1 к многим. Таким образом, в основном у одного пользователя может быть много пользовательских Managablezones (ради простоты зона может быть связана только с 1 пользователем, логически это неверно, но мне не волнует отношения многих ко многим). /p>
Это мой пользователь Managablezones < /code>: < /p>
public virtual User User { get; set; }
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Required]
[Column("ID")]
public int Id { get; set; }
[ForeignKey("User")]
[Required]
[Column("USERNAME")]
public string Username { get; set; }
// ...other properties
< /code>
Тогда у меня есть класс, который в основном является проекцией данных из моей базы данных: < /p>
public Class DataContext
{
public List Users {get; set;}
public DataContext()
{
Users = new List();
}
}
< /code>
DataContext - это «статический» объект, с которым я буду взаимодействовать с данными, добавлять/удалять/обновлять и так далее. Затем я сохраню эти данные обратно в базу данных. Свойства с данными базы данных и обновление данных базы данных с той, что из DataContext .
Чтобы сохранить данные в базе данных, у меня есть, imo, ужасный метод, который, к сожалению, я Не понял, как это работает, поэтому я никогда не трогал его < /p>
private void SaveTable(List entity, bool canUpdate = true, bool canDelete = true)
where T1 : class
{
PrintCallStack(false);
try
{
AMMContext db;
if (AMMContext.DbType == Entity.eDbType.SqLite)
db = new AMMContext(AMMContext.LoadConnectionString());
else
db = new AMMContext();
using (db)
{
List listInDB = (List)Activator.CreateInstance(typeof(List));
DbSet dbSet = null;
foreach (PropertyInfo pInfo in typeof(AMMContext).GetProperties())
{
if (pInfo.GetValue(db) != null)
{
if (pInfo.GetValue(db).GetType() == typeof(DbSet))
{
dbSet = (DbSet)pInfo.GetValue(db);
listInDB = dbSet.ToList();
}
}
}
List idEntityList = null;
if (entity != null)
idEntityList = entity.Select(y => (T2)GetPrimaryKeyValue(y)).ToList();
//List updating = entity.Where(x => idListinDb.Contains((T2)GetPrimaryKeyValue(x))).ToList();
//List adding = entity.Where(x => !idListinDb.Contains((T2)GetPrimaryKeyValue(x))).ToList();
if (canUpdate)
dbSet.AddOrUpdate(entity.ToArray());
if (canDelete)
{
List deleting = dbSet.ToList().Where(x => !idEntityList.Contains((T2)GetPrimaryKeyValue(x))).ToList();
deleting.ForEach(x => dbSet.Attach(x));
dbSet.RemoveRange(deleting);
}
db.SaveChanges();
}
}
catch (Exception e)
{
try
{
PrintCallStack(true);
Log.ErrorFormat($"DataAccess.Save error, transaction rollback occurred | exc:{e.InnerException.InnerException.Message}");
}
catch (Exception ex)
{
Log.ErrorFormat($"DataAccess.Save error, rollback procedure failure");
StringBuilder sb = new StringBuilder();
sb.Append("For entity type : ");
if (entity != null)
{
foreach (T1 item in entity)
{
sb.Append(item.GetType().Name);
sb.Append(" - ");
}
}
Log.ErrorFormat(sb.ToString());
}
}
}
< /code>
This method is called by the DataAccess вокруг кода, заключенный в другой метод, который делает что-то подобное
public void Save(bool allFilter = true, bool usersFilter = false, ...other filters)
{
if (ammUsersFilter | allFilter)
SaveTable(entity: DataContext.Users, canUpdate: true, canDelete: !initialConditions);
// ...same for other filters
}
< /code>
That's about it. The problem is that the collection of UserManageableZones внутри пользователя , он не сохранен в своей таблице. Как и сейчас, когда приложение начинается с нуля, создается база данных, а также создается таблица user_zones .
Я попытался вручную создать запись внутри Таблица user_zones , затем загрузите приложение и увидела, что когда данные собираются из базы данных, у меня фактически есть эта запись внутри пользователя. Это заставляет меня думать, что отношения мудро, моя работа верна. Но я понятия не имею о том, что мне не хватает. < /P>
Ах, просто чтобы упомянуть. Внутри моего пользователя таблицы у меня нет столбца, связанного с user_zones , но я думаю, что это правильно. Вот и все.CREATE TABLE AMM_USER
(
USERNAME VARCHAR(128) NOT NULL,
...
CONSTRAINT PK_AMM_USER PRIMARY KEY (USERNAME)
);
CREATE TABLE USER_ZONES
(
ID INTEGER NOT NULL,
USERNAME VARCHAR(128) NOT NULL,
CONSTRAINT PK_USER_ZONES PRIMARY KEY (ID),
CONSTRAINT FK_USER_ZONES_AMM_USER_USERNAME FOREIGN KEY (USERNAME) REFERENCES AMM_USER(USERNAME)
);
CREATE INDEX FK_USER_ZONES_AMM_USER_USERNAME ON USER_ZONES (USERNAME);
CREATE INDEX IX_USER_ZONES_USERNAME ON USER_ZONES (USERNAME);
Подробнее здесь: https://stackoverflow.com/questions/793 ... ion-relate
.Net Framework & Entity Framework: не сохранение вложенной коллекции организации, связанной с иностранным ключом ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение