繁体   English   中英

使用通用函数查询EF5中的DBSet

[英]Using a Generic Function to query a DBSet in EF5

我已经看到了DbSet的各种实现,但是不确定它们是否是我想要的。

基本上,我们通过EF5 Code First方法建立了一堆DbSet。 我的任务是编写代码,以对照数据库中已有的记录来检查API中的任何更新/发布,以确保仅当它们是新记录时才进行更新/发布。

显然,我不想为每个DBSet编写相同的代码,我想编写一个单一的类/函数,该类/函数将DbSet作为参数/参数,然后检查该DBSet的记录。 它必须是动态的,因为它取决于最终用户以及他们要查询哪个DbSet的操作。

因此,例如,我想做类似call的事情:

CheckDbUniqueRecord(Contracts) ,其中Contracts是从表单传递来的Contract模型的DbSet。

因此,在模型中,我们有public class Contract

在MainDbContext中,我们有多个DbSet,其中之一是public DbSet<Contract> Contracts {get; set;} public DbSet<Contract> Contracts {get; set;}

我希望能够运行相同的代码来检查我们拥有的任何DbSet上的重复记录,方法是简单地通过该行函数传入从特定控制器返回的类/模型...

我知道有一种方法可以做到这一点,但是我不断从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不能用作泛型方法yyyyyy中的类型参数'T'。 从xxxx到yyyy没有隐式引用转换。

有什么解决办法?

首先第一件事:所有这些都被写下并未经测试...

第一件事很简单:您的函数签名...

public static bool CheckDbUniqueRecord<T>(T entity)

或类似扩展方法的东西...

public static bool CheckDbUniqueRecord<T>(this DbContext db, T entity)

基本上,您要做的是在DbContext中查询与您的Entity相对应的DbSet ...

var myDbSet = db.Set<T>();

现在,您需要某种逻辑来找出要检查的属性...可以通过在实体类成员上放置属性来完成...这可以通过检查不是主键字段的所有内容来完成。 ..您必须想出一些要告诉您要测试哪些内容的方法...为了简化此答案,我将为每个具有不名为“ ID”的吸气剂的属性提供一些非常简单的方法。 ..根据您的实现,您很可能希望将其中一些代码移到并非每次都运行的初始化代码块中。

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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM