【问题标题】:public RepoResult create(T item){} Get/Read PK value of itempublic RepoResult create(T item){} 获取/读取项目的 PK 值
【发布时间】:2015-06-03 13:34:20
【问题描述】:

我正在尝试构建一个通用存储库并且遇到了一些问题。我有如下界面:

public interface IGenRepo<T, TKey> where T : class
{
    IQueryable<T> Items { get; }
    T find(TKey pk);
    RepoResult delete(TKey pk);
    RepoResult create(T item);
    RepoResult update(T item);
    RepoResult save();
}

这是实现该接口的类:

public class EFGenRepo<T, TKey> : IGenRepo<T, TKey> where T : class
{
    private PortalEntities context = new PortalEntities();

    public IQueryable<T> Items { get { return context.Set<T>().AsQueryable<T>(); } }

    public T find(TKey pk){}

    public RepoResult delete(TKey pk){}

    public RepoResult create(T item){
        if (item == null) return RepoResult.Failed(RepoMessages.paramIsNull());
        if (true) {//HELP HERE PLEASE, something like: if(item.PKHasNoValue == true)
            context.Set<T>().Add(item);
            return save();
        } else {
            return RepoResult.Failed(RepoMessages.PKIsNotZeroAtCreate());
        }
    }
    public RepoResult update(T item){}

    public RepoResult save(){
        try {
            context.SaveChanges();
            return new RepoResult();
        } catch (Exception e){
            return RepoResult.Failed(RepoMessages.saveChangesFailure(e));
        }
    }

    private RepoResult save(T item){}
}

在我的创建方法中,我想检查传递给该方法的项目的 PK 值。我知道我可以在调用代码之前在我的控制器中检查它,但我想这样做!所以,假设我有一个如下的学生班:

public partial class student
{       
    public int id { get; set; }
    public string naam { get; set; }
}

传递一个 id 为 0 的学生对象,现在我希望 if 语句评估为真。如果学生对象已经有一个 id,它必须评估为 false。但是我该如何检查这个。我想我必须使用类似下面的代码,但我没有这方面的技能:

typeof(TKey).Name;
item.GetType().Name;

非常感谢任何帮助!

【问题讨论】:

    标签: c# entity-framework-6 asp.net-mvc-5.2 .net-4.5.2


    【解决方案1】:

    我做的解决方案是创建一个界面:

    public interface IPKProvider
    {
        bool PKHasNoValue();
    }
    

    我让我所有的自动生成的 EF 类(学生只是一个例子)实现这个接口(在一个单独的部分类文件中)

    所以单独的学生班级看起来像这样:

    public partial class schakeling : IPKProvider
    {
        public bool PKHasNoValue() {
            return this.id == 0;
        }
    }
    

    另一个 EF 实体,假设用户将如下所示:

    public partial class user: IPKProvider
    {
        public bool PKHasNoValue() {
            return string.IsNullOrEmpty(this.username);
        }
    }
    

    现在我可以在我的 EFGenRepo 类中实现 IPKProvider 接口,如下所示:

    public class EFGenRepo<T, TKey> : IGenRepo<T, TKey> where T : class, IPKProvider
    {
        private PortalEntities context = new PortalEntities();
    
        public IQueryable<T> Items { get { return context.Set<T>().AsQueryable<T>(); } }
    
        public T find(TKey pk){}
    
        public RepoResult delete(TKey pk){}
    
        public RepoResult create(T item){
            if (item == null) return RepoResult.Failed(RepoMessages.paramIsNull());
            if (item.PKHasNoValue()) {//<----------PROBLEM SOLVED
                context.Set<T>().Add(item);
                return save();
            } else {
                return RepoResult.Failed(RepoMessages.PKIsNotZeroAtCreate());
            }
        }
        public RepoResult update(T item){}
    
        public RepoResult save(){
            try {
                context.SaveChanges();
                return new RepoResult();
            } catch (Exception e){
                return RepoResult.Failed(RepoMessages.saveChangesFailure(e));
            }
        }
    
        private RepoResult save(T item){}
    }
    

    这种方法有效,但也有一些缺点。做的工作并不多,我必须为每个自动生成的 EF 实体手动构建一个额外的部分类。如果将来数据库结构发生变化(当然不会发生很多),我也必须手动更新它们。它有效,但我只是不喜欢这种方式。任何 cmets 将不胜感激。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-23
      • 1970-01-01
      • 1970-01-01
      • 2016-07-16
      • 1970-01-01
      • 1970-01-01
      • 2019-12-27
      • 1970-01-01
      相关资源
      最近更新 更多