IDisposable

public class Project
{
public string Id { get; set; }
public string Name { get; set; }

public virtual BaseInfo BaseInfo { get; set; }

public Project()
{
this.Id = Guid.NewGuid().ToString();
this.BaseInfo = new BaseInfo();
this.BaseInfo.ProjectId = this.Id;
}
}

public class BaseInfo
{
public string ProjectId { get; set; }
public string No { get; set; }
public double Area { get; set; }

public virtual Project Project { get; set; }
}

public class ProjectEntityTypeConfiguration : EntityTypeConfiguration<Project>
{
public ProjectEntityTypeConfiguration()
{
ToTable("_Project");
HasKey(t => t.Id);

// 这种配置必须手工先删除Info项,再删除Project
HasOptional(p => p.BaseInfo).WithRequired(i => i.Project);

// 这种配置无法删除对象
//HasRequired(p => p.BaseInfo).WithRequiredDependent(i => i.Project);
}
}

public class BaseInfoEntityTypeConfiguration : EntityTypeConfiguration<BaseInfo>
{
public BaseInfoEntityTypeConfiguration()
{
ToTable("_BaseInfo");
HasKey(t => t.ProjectId);
}
}

public class DBContext : DbContext
{
public DBContext() : base()
{

}

public DBContext(string nameOrConnectionString) : base(nameOrConnectionString)
{

}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
if (modelBuilder == null) { throw new ArgumentNullException("modelBuilder"); }

var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => !String.IsNullOrEmpty(type.Namespace))
.Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
foreach (var type in typesToRegister)
{
dynamic configurationInstance = Activator.CreateInstance(type);
modelBuilder.Configurations.Add(configurationInstance);
}
}
}

internal class InternalEntityStore<TEntity> where TEntity : class
{
public DbContext Context
{
get;
private set;
}

public IQueryable<TEntity> EntitySet
{
get
{
return this.DbEntitySet;
}
}

public DbSet<TEntity> DbEntitySet
{
get;
private set;
}

public InternalEntityStore(DbContext context)
{
this.Context = context;
this.DbEntitySet = context.Set<TEntity>();
}

public virtual Task<TEntity> GetByIdAsync(object id)
{
return this.DbEntitySet.FindAsync(new object[]
{
id
});
}

public void Create(TEntity entity)
{
this.DbEntitySet.Add(entity);
}

public void Delete(TEntity entity)
{
this.DbEntitySet.Remove(entity);
}

public virtual void Update(TEntity entity)
{
if (entity != null)
{
this.Context.Entry<TEntity>(entity).State = EntityState.Modified;
}
}
}

public class EntityStore<TEntity> : IDisposable where TEntity : class
{
public DBContext Context
{
get;
private set;
}

public IQueryable<TEntity> EntitySet
{
get
{
return this._EntityStore.EntitySet;
}
}

private InternalEntityStore<TEntity> _EntityStore;

public EntityStore(DBContext context)
{
if (context == null)
{
throw new ArgumentNullException("context");
}
this.Context = context;
this._EntityStore = new InternalEntityStore<TEntity>(context);
}

public virtual async Task CreateAsync(TEntity entity)
{
this.ThrowIfDisposed();
if (entity == null) { throw new ArgumentNullException("entity"); }

this._EntityStore.Create(entity);
await this.Context.SaveChangesAsync();
}

public virtual async Task DeleteAsync(TEntity entity)
{
this.ThrowIfDisposed();
if (entity == null) { throw new ArgumentNullException("entity"); }

this._EntityStore.Delete(entity);
await this.Context.SaveChangesAsync();
}

public virtual async Task UpdateAsync(TEntity entity)
{
this.ThrowIfDisposed();
if (entity == null) { throw new ArgumentNullException("entity"); }

this._EntityStore.Update(entity);
await this.Context.SaveChangesAsync();
}

public virtual Task<TEntity> FindByIdAsync(string id)
{
this.ThrowIfDisposed();
if (string.IsNullOrWhiteSpace(id))
{
throw new ArgumentException("id can not be null or empty.");
}
return this._EntityStore.GetByIdAsync(id);
}

private bool _disposed;
public bool DisposeContext
{
get;
set;
}
private void ThrowIfDisposed()
{
if (this._disposed)
{
throw new ObjectDisposedException(base.GetType().Name);
}
}
protected virtual void Dispose(bool disposing)
{
if (this.DisposeContext && disposing && this.Context != null)
{
this.Context.Dispose();
}
this._disposed = true;
this.Context = null;
this._EntityStore = null;
}

public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
}

public class ProjectStore : EntityStore<Project>
{
public ProjectStore(DBContext context):base(context)
{
_baseInfoStore = new EntityStore<BaseInfo>(context);
}

private EntityStore<BaseInfo> _baseInfoStore;

public override async Task DeleteAsync(Project entity)
{
var info = await _baseInfoStore.FindByIdAsync(entity.Id);
if(info!=null)
{
await _baseInfoStore.DeleteAsync(info);
}
await base.DeleteAsync(entity);
}

private bool _disposed;
protected override void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_baseInfoStore.Dispose();
}
_disposed = true;
}
base.Dispose(disposing);
}
}

时间: 2024-10-13 12:02:03

IDisposable的相关文章

强制回收和IDisposable.Dispose方法

如果某对象的 Dispose 方法被调用一次以上,则该对象必须忽略第一次调用后的所有调用. 如果对象的 Dispose 方法被多次调用,该对象一定不要引发异常. 除Dispose 之外的实例方法在资源已释放时会引发 ObjectDisposedException. 用户可能期望资源类型使用特定的约定来表示已分配状态和已释放状态.流类即是这样一种示例,传统上认为它们要么打开要么关闭.具有此种约定的类的实施者可能选择实现具有自定义名称(如“Close”)的公用方法来调用 Dispose 方法. 因为

IDisposable接口

User.cs public class User { public int id { get; set; } public string name { get; set; } } BaseService.cs public abstract class BaseService:IDisposable { /// <summary> /// 要释放的对象 /// </summary> public IList<IDisposable> DisposablesObject

c#之如何正确地实现IDisposable接口

见实例: public class TestClass : IDisposable { //供程序员显式调用的Dispose方法 public void Dispose() { //调用带参数的Dispose方法,释放托管和非托管资源 Dispose(true); //手动调用了Dispose释放资源,那么析构函数就是不必要的了,这里阻止GC调用析构函数 GC.SuppressFinalize(this); } //protected的Dispose方法,保证不会被外部调用. //传入bool值

通过IEnumerable和IDisposable实现可暂停和取消的任务队列

一般来说,软件中总会有一些长时间的操作,这类操作包括下载文件,转储数据库,或者处理复杂的运算. 一种处理做法是,在主界面上提示正在操作中,有进度条,其他部分不可用.这里带来很大的问题, 使用者不知道到底执行到什么程度,无法暂停或者取消任务.而即使花了很大的力气实现了暂停和取消,也很难形成通用的模块. 另一种是类似下载工具那样,有多个在任务队列中的任务,提示用户当前执行了多少,可以选择暂停或者取消任务.如下图: 显然后者的用户体验更好.那么,如何实现它呢? 应当考虑,这个任务管理器应当尽可能通用,

C#中的IDisposable模式

当谈到垃圾回收,在C#中,托管资源的垃圾回收是通过CLR的Garbage Collection来实现的,Garbage Collection会调用堆栈上对象的析构函数完成对象的释放工作:而对于一些非托管资源,比如数据库链接对象等,需要实现IDisposable接口进行手动的垃圾回收.那么什么时候使用Idisposable接口,以及如何使用呢? public interface IDisposable { void Dispose(); } public class DisposablClass

IDisposable .Dispose 方法

如果某对象的 Dispose 方法被调用一次以上,则该对象必须忽略第一次调用后的所有调用. 如果对象的 Dispose 方法被多次调用,该对象一定不要引发异常. 除Dispose 之外的实例方法在资源已释放时会引发 ObjectDisposedException. 用户可能期望资源类型使用特定的约定来表示已分配状态和已释放状态.流类即是这样一种示例,传统上认为它们要么打开要么关闭.具有此种约定的类的实施者可能选择实现具有自定义名称(如“Close”)的公用方法来调用 Dispose 方法. 因为

【C#学习笔记】 IDisposable 接口

托管资源指的是.NET可以自动进行回收的资源,主要是指托管堆上分配的内存资源.托管资源的回收工作是不需要人工干预的,有.NET运行库在合适调用垃圾回收器进行回收. 非托管资源指的是.NET不知道如何回收的资源,最常见的一类非托管资源是包装操作系统资源的对象,例如文件,窗口,网络连接,数据库连接,画刷,图标等.这类资源,垃圾回收器在清理的时候会调用Object.Finalize()方法.默认情况下,方法是空的,对于非托管对象,需要在此方法中编写回收非托管资源的代码,以便垃圾回收器正确回收资源. 在

转:正确实现 IDisposable 接口

MSDN建议按照下面的模式实现IDisposable接口: public class Foo: IDisposable { public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!m_disposed) { if (disposing) { // Release managed resources } // R

【转】C#中对IDisposable接口的理解

IDisposable接口定义:定义一种释放分配的资源的方法. .NET 平台在内存管理方面提供了GC(Garbage Collection),负责自动释放托管资源和内存回收的工作,但它无法对非托管资源进行释放,这时我们必须自己提供方法来释放对象内分配的非托管资源,比如你在对象的实现代码中使用了一个COM对象 最简单的办法可以通过实现Finalize()来释放非托管资源,因为GC在释放对象时会检查该对象是否实现了 Finalize() 方法. 有一种更好的,那就是通过实现一个接口显式的提供给客户