Так как blockize и getAvailableBlocks
устарели
, этот код можно использовать
примечание на основе приведенного выше ответа пользователя 802467
public long sd_card_free(){
File path = Environment.getExternalStorageDirectory();
StatFs stat = new StatFs(path.getPath());
long availBlocks = stat.getAvailableBlocksLong();
long blockSize = stat.getBlockSizeLong();
long free_memory = availBlocks * blockSize;
return free_memory;
}
мы можем использовать getAvailableBlocksLong
и getBlockSizeLong
Причина сбоя второго блока кода заключается в том, что EF не может найти объект в ObjectStateManager - т.е. когда он извлекает объекты из базы данных, он помещает их в диспетчер состояний, чтобы отслеживать их - это похоже на Образец карты идентичности . Несмотря на наличие EntityKey, ваш объект не находится в диспетчере состояний, поэтому EF не может сохранить изменения. Вы можете обойти это, поместив объект в диспетчер состояний самостоятельно, но вы должны быть немного скрытными.
Это работает:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, Department model)
{
var entitySetName = db.DefaultContainerName + "." + model.GetType().Name;
var entityKey = new System.Data.EntityKey(entitySetName, "Id", model.Id);
db.Attach(new Department{Id = id, EntityKey = entityKey});
db.AcceptAllChanges();
db.ApplyPropertyChanges(entitySetName, model);
db.SaveChanges();
}
... но это не очень чисто. По сути, это присоединение «пустого» объекта только с ключом сущности, принятие всех изменений и последующий вызов ApplyPropertyChanges с реальными обновленными значениями.
Здесь ' s то же самое, заключенное в метод расширения - это должно работать для всего, что использует единственный столбец db для первичного ключа. Единственная интересная часть вызова метода заключается в том, что вам нужно указать ему, как найти ключевое свойство через делегат в качестве второго аргумента метода расширения:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, Department model)
{
db.ApplyDetachedPropertyChanges(model, x => x.Id);
db.SaveChanges();
}
и метода расширения:
public static class EfExtensions
{
public static void ApplyDetachedPropertyChanges<T>(this ObjectContext db, T entity, Func<T, int> getIdDelegate)
where T : EntityObject
{
var entitySetName = db.DefaultContainerName + "." + entity.GetType().Name;
var id = getIdDelegate(entity);
var entityKey = new EntityKey(entitySetName, "Id", id);
db.Attach(new Department {Id = id, EntityKey = entityKey});
db.AcceptAllChanges();
db.ApplyPropertyChanges(entitySetName, entity);
}
}
Когда метод расширения вызывает AcceptAllChanges, вам нужно быть осторожным при вызове этого, если вы выполняете обновления сразу для нескольких объектов - вы можете легко «потерять» обновления, если не будете осторожны. Следовательно, этот подход действительно подходит только для простых сценариев обновления - например, для множества методов действий MVC :)
Единственная интересная часть вызова метода заключается в том, что вам нужно указать ему, как найти ключевое свойство через делегат в качестве второго аргумента метода расширения:[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, Department model)
{
db.ApplyDetachedPropertyChanges(model, x => x.Id);
db.SaveChanges();
}
и метода расширения:
public static class EfExtensions
{
public static void ApplyDetachedPropertyChanges<T>(this ObjectContext db, T entity, Func<T, int> getIdDelegate)
where T : EntityObject
{
var entitySetName = db.DefaultContainerName + "." + entity.GetType().Name;
var id = getIdDelegate(entity);
var entityKey = new EntityKey(entitySetName, "Id", id);
db.Attach(new Department {Id = id, EntityKey = entityKey});
db.AcceptAllChanges();
db.ApplyPropertyChanges(entitySetName, entity);
}
}
Когда метод расширения вызывает AcceptAllChanges, вам нужно быть осторожным при вызове этого, если вы выполняете обновления сразу для нескольких объектов - вы можете легко «потерять» обновления, если не будете осторожны. Следовательно, этот подход действительно подходит только для простых сценариев обновления - например, для множества методов действий MVC :)
Единственная интересная часть вызова метода заключается в том, что вам нужно указать ему, как найти ключевое свойство через делегат в качестве второго аргумента метода расширения:[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, Department model)
{
db.ApplyDetachedPropertyChanges(model, x => x.Id);
db.SaveChanges();
}
и метода расширения:
public static class EfExtensions
{
public static void ApplyDetachedPropertyChanges<T>(this ObjectContext db, T entity, Func<T, int> getIdDelegate)
where T : EntityObject
{
var entitySetName = db.DefaultContainerName + "." + entity.GetType().Name;
var id = getIdDelegate(entity);
var entityKey = new EntityKey(entitySetName, "Id", id);
db.Attach(new Department {Id = id, EntityKey = entityKey});
db.AcceptAllChanges();
db.ApplyPropertyChanges(entitySetName, entity);
}
}
Когда метод расширения вызывает AcceptAllChanges, вам нужно быть осторожным при вызове этого, если вы выполняете обновления сразу для нескольких объектов - вы можете легко «потерять» обновления, если не будете осторожны. Следовательно, этот подход действительно подходит только для простых сценариев обновления - например, для множества методов действий MVC :)
public static class EfExtensions
{
public static void ApplyDetachedPropertyChanges<T>(this ObjectContext db, T entity, Func<T, int> getIdDelegate)
where T : EntityObject
{
var entitySetName = db.DefaultContainerName + "." + entity.GetType().Name;
T newEntity = Activator.CreateInstance<T>();
newEntity.EntityKey = db.CreateEntityKey(entitySetName, entity);
Type t = typeof(T);
foreach(EntityKeyMember keyMember in newEntity.EntityKey.EntityKeyValues) {
PropertyInfo p = t.GetProperty(keyMember.Key);
p.SetValue(newEntity, keyMember.Value, null);
}
db.Attach(newEntity);
//db.AcceptAllChanges();
db.ApplyPropertyChanges(entitySetName, entity);
}
}
Попробуйте использовать приведенный ниже код и сообщите мне, работает ли он для вас.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Guid id, Department Model)
{
using (var context = new EntityContext())
{
try
{
Object entity = null;
IEnumerable<KeyValuePair<string, object>> entityKeyValues =
new KeyValuePair<string, object>[] {
new KeyValuePair<string, object>("DepartmentID", id) };
// Create the key for a specific SalesOrderHeader object.
EntityKey key = new EntityKey("EntityContext.Deparment",
entityKeyValues);
// Get the object from the context or the persisted store by its key.
if (context.TryGetObjectByKey(key, out entity))
{
context.ApplyPropertyChanges(key.EntitySetName, Model);
context.SaveChanges();
}
else
{
// log message if we need
//"An object with this key could not be found."
}
}
catch (EntitySqlException ex)
{
// log message
}
}
}