通用存储库模式 IEntity 属性 区分大小写
Generic Repository Pattern IEntity property case sensitivity
我在我的应用程序中使用通用存储库模式。我正在尝试这个 post http://www.remondo.net/repository-pattern-example-csharp/。问题是,数据库代码生成工具(代码优先来自现有数据库)生成以下模型:
[Table("TableName1")]
public partial class TableName1 : IEntity
{
public int ID { get; set; }
[StringLength(50)]
public string Name { get; set; }
::::::::
}
[Table("TableName2")]
public partial class TableName2 : IEntity
{
public int Id { get; set; }
[StringLength(50)]
public string Name { get; set; }
::::::::
}
而且我刚刚在上述数据库模型中应用了 IEntity,但是 TableName2 class 中存在问题,因为 IEntity 接口具有 'ID' 属性 而不是 'Id'。这是一个
public interface IEntity
{
int ID { get; }
}
那么如何在不查看大小写的情况下将此 IEntity 转换为接受属性?如果我不想为每个 table?
创建单独的独立新模型,我需要最简单的解决方案
如果您使用代码优先方法,Entity Framework 会在生成 table 时自动将您的实体名称复数化,因此让我们先为您的问题添加一些上下文并删除所有抽象,假设我们正在创建一个用户存储库,实体框架将自动生成一个 Users
table.
public partial class User : IEntity
{
public int Id { get; set; }
[StringLength(50)]
public string Name { get; set; }
}
public partial class BlogPost : IEntity
{
public int Id { get; set; }
[StringLength(50)]
public string Title { get; set; }
}
public interface IEntity
{
int Id { get; }
}
没有办法绕过大小写规则,这是一个规则,尽管我们喜欢做牛仔,但你写的东西甚至不能编译,因为 interface
是合同。如果 class
实施 合同 ,它必须实施 合同 概述的所有内容; 属性 Id
至少有一个 getter
.
我查看了您提供的 link,它没有告诉您应该如何正确实施 IRepository
,您的每个实体都应该有自己的存储库,我会修改那个界面,让它变成这样:
public interface IRepository<T> where T : class, IEntity
{
void Insert(T entity);
void Delete(T entity);
IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate);
IQueryable<T> GetAll();
T GetById(int id);
}
我们在这里所做的是,我们已经说过 IRepository
将与任何实现 IRepository
接受实现 IEntity
契约的 type parameter
的存储库一起工作。
public class UserRepository<User> : IRepository<User>
{
protected Table<User> DataTable;
public Repository(DataContext dataContext)
{
DataTable = dataContext.GetTable<User>();
}
#region IRepository<T> Members
public void Insert(User entity)
{
DataTable.InsertOnSubmit(entity);
}
public void Delete(User entity)
{
DataTable.DeleteOnSubmit(entity);
}
public IQueryable<User> SearchFor(Expression<Func<User, bool>> predicate)
{
return DataTable.Where(predicate);
}
public IQueryable<User> GetAll()
{
return DataTable;
}
public User GetById(int id)
{
// Sidenote: the == operator throws NotSupported Exception!
// 'The Mapping of Interface Member is not supported'
// Use .Equals() instead
return DataTable.Single(e => e.Id.Equals(id));
}
#endregion
}
我使用的方法现在被 Entity Framework 本身克服了,不确定 Entity Framework 的哪个版本。下面的代码显示了 Entity Framework 的通用存储库模式的一个漂亮而干净的实现。这里不需要 IEntity 接口,因为我们使用了 DbSet class.
的方便的 Find 扩展方法
这里是 IRepository:
public interface IRepository<T>
{
void Insert(T entity);
void Delete(T entity);
IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate);
IQueryable<T> GetAll();
T GetById(int id);
}
这是存储库:
public class Repository<T> : IRepository<T> where T : class
{
protected DbSet<T> DbSet;
public Repository(DbContext dataContext)
{
DbSet = dataContext.Set<T>();
}
#region IRepository<T> Members
public void Insert(T entity)
{
DbSet.Add(entity);
}
public void Delete(T entity)
{
DbSet.Remove(entity);
}
public IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate)
{
return DbSet.Where(predicate);
}
public IQueryable<T> GetAll()
{
return DbSet;
}
public T GetById(int id)
{
return DbSet.Find(id);
}
#endregion
}
保持 Entity Framework Code First 代码不变。现在,我们准备在应用程序中使用这个通用存储库,方法如下:
using (var dataContext = new UserBaseContext())
{
var userRepository = new Repository<Users>(dataContext);
Users user = userRepository
.SearchFor(c => c.Name.StartsWith("A"))
.Single();
//do other stuff
}
而且这不会抱怨外壳等问题,很高兴我有了第一个可用的通用存储库:)
我在我的应用程序中使用通用存储库模式。我正在尝试这个 post http://www.remondo.net/repository-pattern-example-csharp/。问题是,数据库代码生成工具(代码优先来自现有数据库)生成以下模型:
[Table("TableName1")]
public partial class TableName1 : IEntity
{
public int ID { get; set; }
[StringLength(50)]
public string Name { get; set; }
::::::::
}
[Table("TableName2")]
public partial class TableName2 : IEntity
{
public int Id { get; set; }
[StringLength(50)]
public string Name { get; set; }
::::::::
}
而且我刚刚在上述数据库模型中应用了 IEntity,但是 TableName2 class 中存在问题,因为 IEntity 接口具有 'ID' 属性 而不是 'Id'。这是一个
public interface IEntity
{
int ID { get; }
}
那么如何在不查看大小写的情况下将此 IEntity 转换为接受属性?如果我不想为每个 table?
创建单独的独立新模型,我需要最简单的解决方案如果您使用代码优先方法,Entity Framework 会在生成 table 时自动将您的实体名称复数化,因此让我们先为您的问题添加一些上下文并删除所有抽象,假设我们正在创建一个用户存储库,实体框架将自动生成一个 Users
table.
public partial class User : IEntity
{
public int Id { get; set; }
[StringLength(50)]
public string Name { get; set; }
}
public partial class BlogPost : IEntity
{
public int Id { get; set; }
[StringLength(50)]
public string Title { get; set; }
}
public interface IEntity
{
int Id { get; }
}
没有办法绕过大小写规则,这是一个规则,尽管我们喜欢做牛仔,但你写的东西甚至不能编译,因为 interface
是合同。如果 class
实施 合同 ,它必须实施 合同 概述的所有内容; 属性 Id
至少有一个 getter
.
我查看了您提供的 link,它没有告诉您应该如何正确实施 IRepository
,您的每个实体都应该有自己的存储库,我会修改那个界面,让它变成这样:
public interface IRepository<T> where T : class, IEntity
{
void Insert(T entity);
void Delete(T entity);
IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate);
IQueryable<T> GetAll();
T GetById(int id);
}
我们在这里所做的是,我们已经说过 IRepository
将与任何实现 IRepository
接受实现 IEntity
契约的 type parameter
的存储库一起工作。
public class UserRepository<User> : IRepository<User>
{
protected Table<User> DataTable;
public Repository(DataContext dataContext)
{
DataTable = dataContext.GetTable<User>();
}
#region IRepository<T> Members
public void Insert(User entity)
{
DataTable.InsertOnSubmit(entity);
}
public void Delete(User entity)
{
DataTable.DeleteOnSubmit(entity);
}
public IQueryable<User> SearchFor(Expression<Func<User, bool>> predicate)
{
return DataTable.Where(predicate);
}
public IQueryable<User> GetAll()
{
return DataTable;
}
public User GetById(int id)
{
// Sidenote: the == operator throws NotSupported Exception!
// 'The Mapping of Interface Member is not supported'
// Use .Equals() instead
return DataTable.Single(e => e.Id.Equals(id));
}
#endregion
}
我使用的方法现在被 Entity Framework 本身克服了,不确定 Entity Framework 的哪个版本。下面的代码显示了 Entity Framework 的通用存储库模式的一个漂亮而干净的实现。这里不需要 IEntity 接口,因为我们使用了 DbSet class.
的方便的 Find 扩展方法这里是 IRepository:
public interface IRepository<T>
{
void Insert(T entity);
void Delete(T entity);
IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate);
IQueryable<T> GetAll();
T GetById(int id);
}
这是存储库:
public class Repository<T> : IRepository<T> where T : class
{
protected DbSet<T> DbSet;
public Repository(DbContext dataContext)
{
DbSet = dataContext.Set<T>();
}
#region IRepository<T> Members
public void Insert(T entity)
{
DbSet.Add(entity);
}
public void Delete(T entity)
{
DbSet.Remove(entity);
}
public IQueryable<T> SearchFor(Expression<Func<T, bool>> predicate)
{
return DbSet.Where(predicate);
}
public IQueryable<T> GetAll()
{
return DbSet;
}
public T GetById(int id)
{
return DbSet.Find(id);
}
#endregion
}
保持 Entity Framework Code First 代码不变。现在,我们准备在应用程序中使用这个通用存储库,方法如下:
using (var dataContext = new UserBaseContext())
{
var userRepository = new Repository<Users>(dataContext);
Users user = userRepository
.SearchFor(c => c.Name.StartsWith("A"))
.Single();
//do other stuff
}
而且这不会抱怨外壳等问题,很高兴我有了第一个可用的通用存储库:)