使用泛型函数查询EF5中的DBSet
我看到了DbSet的各种实现,但我不确定它们是我正在寻找的。使用泛型函数查询EF5中的DBSet
基本上我们有一堆通过EF5 Code First方法设置的DbSet。我有一个编写代码的任务,根据我们在数据库中已有的记录来检查进入API的任何更新/帖子,以确保它们只有在新记录时才更新/张贴。
显然我不想为每个这些DBSet编写相同的代码,我想编写一个类/函数,它将能够将DbSet作为参数/参数,然后检查DBSet作为记录。它必须是动态的,因为它是依赖于最终用户和他们在做什么哪个DbSet将需要查询...
因此,例如,我想要做的事,如呼叫:
CheckDbUniqueRecord(Contracts)
其中合同是从表单传入的合同模型的DbSet。
所以在这个模型中,我们有public class Contract
,并在MainDbContext我们有多个DbSet的其中之一是public DbSet<Contract> Contracts {get; set;}
我希望能够运行相同的代码来检查任何重复记录的DbSets我们通过简单地传递从该特定的控制器返回的类/模型与该一行功能...
我知道有一种方法来实现这一点,但我不断收到错误消息/类型来自C#的错误表明类型不匹配,等等......
任何帮助将不胜感激。
更新:我只会需要此检查数据库中的重复记录,而不是更新。在调用Put函数之前,我将处理客户端的检查更新。
我有下面的代码这是非常近的工作:
public interface getId
{
int Id { get; set; }
}
public class Check : getId
{
public int Id { get; set; }
public static bool CheckDBUniqueRecord<T>(T entity) where T : class, getId
{
MainDbContext db = new MainDbContext(Utility.PortalConnectionString());
var myDbSet = db.Set<T>().ToList();
foreach (var d in myDbSet)
{
d.Id = 0;
if (d == entity) return true;
}
return false;
}
}
通过使用通用约束,但是我得到的方法调用的错误:类型XXXX不能用作类型参数“T '在通用方法yyyyyy。没有从xxxx到yyyy的隐式引用转换。
这是什么修复?
第一件事,第一:这一切只是写下来的和未经考验......
的第一件事情很简单:你的函数签名......
public static bool CheckDbUniqueRecord<T>(T entity)
或类似像extensionmethod东西。 ..
public static bool CheckDbUniqueRecord<T>(this DbContext db, T entity)
基本上你想要做的就是查询您的DbContext为对应于你的实体的DbSet ...
var myDbSet = db.Set<T>();
现在你需要某种逻辑来找出你想检查哪些属性......这可以通过在你的实体类成员上放置属性来完成......这可以通过检查所有不是主键字段的东西来完成......你必须想出一些东西来告诉你测试哪些东西......为了简单起见,我将简单地介绍一些非常简单的事情,对于每个属性都有一个没有被命名为“ID”的getter ......根据您的实现,您最有可能想要将这些代码移动到初始化代码块不会每次都运行...
var t = typeof(T);
var pInfos = t.GetProperties(BindingFlags.Public|BindingFlags.Instance).Where(x=>x.Name!="ID" && x.CanRead).ToArray();
Expression exp=null;
Expression pT = Expression.Parameter(t);
foreach(var p in pInfos)
{
Expression m = Expression.Property(pT,p);
Expression c = Expression.Constant(p.GetValue(entity));
if(tmp==null)
{
tmp=Expression.Equal(m,c);
}
else
{
tmp=Expression.AndAlso(tmp,Expression.Equal(m,c));
}
}
var myLambda=Expression.Lambda<Func<T,bool>>(tmp,pT);
return myDbSet.AsQueryable().Any(myLambda);
我在想因为我会知道标识符I会搜索DB的MemberId,我会得到记录,然后我会遍历每个记录中的每一列,并将其与 – MattE
记录中的列进行比较为什么你想实现所有与你的memberid匹配的实体?如果你想知道这样的记录是否存在,请询问DBMS ....你想知道什么会导致类似SELECT count(*)> 0 FROM ... WHERE Property1 ='Value1'AND Property2 ='Value2 '... – DarkSquirrel42
所以,换句话说,你想要一个通用的方法来检查一个任意的实体在数据库中的存在,对不对?你如何期待检查完成?你想如何确定哪些字段将被包含在比较中?成员的属性?除ID之外的所有字段? – DarkSquirrel42
您需要使用泛型方法来启动,然后在其中使用typeof(T),其中T是类,然后将每种类型抽象为具体方法,或者您可以使用反射T来尝试获取对象属性和使用它来执行保存更新等,您仍然需要将一些东西传递给泛型方法以确定需要创建哪种类型的CRUD。您可以从简单的单一主键对象开始,然后当确信这个工作时,为更复杂的类型编写重载方法。 – bilpor
是的,实体将始终存在于数据库中,所以这不是一个问题。该检查将针对所有字段运行......基本上,我会遍历数据库记录中的每个字段,并检查传入的模型的值。如果所有字段相同,则后/更新将不会运行。发现任何已更改的字段后,它将跳出循环并运行发布/更新。我实际上只是需要它的职位,因为我会在运行更新之前检查客户端的更新。所以基本上只是为了确保数据库中没有重复的记录。 – MattE