Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在泛型存储库使用者类中创建泛型方法_C#_Generics - Fatal编程技术网

C# 在泛型存储库使用者类中创建泛型方法

C# 在泛型存储库使用者类中创建泛型方法,c#,generics,C#,Generics,我想在泛型存储库使用者类中创建泛型方法 以下是我在泛型存储库类中的泛型方法: public class CosmosDBRepository<T> : ICosmosDBRepository<T> where T : class { public async Task<IEnumerable<T>> GetItemsAsync(Expression<Func<T, bool>> predicate, Exp

我想在泛型存储库使用者类中创建泛型方法

以下是我在泛型存储库类中的泛型方法:

public class CosmosDBRepository<T> : ICosmosDBRepository<T> where T : class
    {
     public async Task<IEnumerable<T>> GetItemsAsync(Expression<Func<T, bool>> predicate, Expression<Func<T, object>> orderByDesc, int takeCount = -1)
    
            {
                var criteria = _container.GetItemLinqQueryable<T>(true)
                    .Where(predicate)
                    .OrderByDescending(orderByDesc)
                    .ToFeedIterator();
    
                var query = criteria;
    
                var results = new List<T>();
                while (query.HasMoreResults)
                {
                    if (takeCount > -1 && results.Count >= takeCount) break;
                    results.AddRange(await query.ReadNextAsync());
                }
    
                return results;
            }
}
公共类CosmosDBRepository:ICOSOMOSDBRepository其中T:class
{
公共异步任务GetItemsAsync(表达式谓词,表达式orderByDesc,int takeCount=-1)
{
var条件=_container.GetItemLinqQueryable(true)
.Where(谓词)
.OrderByDescending(orderByDesc)
.ToFeedIterator();
var查询=条件;
var results=新列表();
while(query.HasMoreResults)
{
如果(takeCount>-1&&results.Count>=takeCount)中断;
results.AddRange(wait query.ReadNextAsync());
}
返回结果;
}
}
通用存储库使用者类:

 public class SubscriptionRepository : CosmosDBRepository<Subscription>, ISubscriptionRepository
    {
        public SubscriptionRepository(
            ICosmosDBClient client
            ) : base(client)
        {

        }

        
        public async Task<List<T>> GetSubscriptions<T, TE>(
            TE eventItem,
            params SubscriptionAction[] subscriptionAction)
                where T : Subscription
                where TE : Event
        {
            Expression<Func<T, bool>> predicate = (x) => x.EventType == eventItem.EventType
                            && x.IsActive;

            predicate = predicate.And(x => subscriptionAction.Contains(x.Action));

            if (!string.IsNullOrEmpty(eventItem.PayerNumber))
            {
                predicate = predicate.And(x => x.PayerNumber == eventItem.PayerNumber);
            }
            else if (!string.IsNullOrEmpty(eventItem.AccountNumber))
            {
                predicate = predicate.And(x => x.AccountNumber == eventItem.AccountNumber);
            }

            var result = await GetItemsAsync(predicate, o => o.PayerNumber);

            return result.ToList();
        }
    }
公共类SubscriptionRepository:CosmosDBRepository,ISubscriptionRepository
{
公共订阅存储库(
ICosmosDBClient客户端
):基本(客户端)
{
}
公共异步任务订阅(
事件项,
参数SubscriptionAction[]SubscriptionAction)
其中T:订阅
其中TE:事件
{
表达式谓词=(x)=>x.EventType==eventItem.EventType
&&十是积极的;
predicate=predicate.And(x=>subscriptionAction.Contains(x.Action));
如果(!string.IsNullOrEmpty(eventItem.PayerNumber))
{
谓词=谓词。和(x=>x.PayerNumber==eventItem.PayerNumber);
}
如果(!string.IsNullOrEmpty(eventItem.AccountNumber))
{
谓词=谓词。和(x=>x.AccountNumber==eventItem.AccountNumber);
}
var result=await GetItemsAsync(谓词,o=>o.PayerNumber);
返回result.ToList();
}
}
现在我想在
SubscriptionRepository
类中创建泛型方法
GetSubscriptions

你能建议我如何做到这一点吗

目前我遇到以下编译时错误:

无法从“System.Linq.Expression”转换为 'System.Linq.Expression.Expression'

也许你应该用

Expression<Func<Subscription, bool>> predicate = (x) => x.EventType == eventItem.EventType
                        && x.IsActive;
表达式谓词=(x)=>x.EventType==eventItem.EventType
&&十是积极的;
由于您使用的是泛型类型T而不是Subscription(即使您检查T应该是Subscription或子类),因此无法分配表达式

在您的例子中,我看不到在GetSubscriptions中使用泛型而不是直接使用实类型的好处

检查此示例:

   public class Test
   {
   }

   Expression<Func<Test, bool>> temp1 = (t) => true;
   Expression<Func<object, bool>> temp2 = temp1;
公共类测试
{
}
表达式temp1=(t)=>true;
表达式temp2=temp1;
此示例将在第二行失败。甚至is Test是对象的子类(与.NET中的所有类一样)

编辑

如下文所述:

Func的T(第一个泛型类型参数)具有“in”关键字。这意味着:

此类型参数是逆变的。也就是说,您可以使用 指定的类型或派生较少的任何类型

因为T可以是Subscription的子级(比如说“ChildSubscription”)。
当您尝试将Func分配给Func时,您将尝试分配一个更派生的函数。

这里至少有两个问题,这两个问题性质相同-您试图创建一个通用方法来包装一个具体的
cosmosdbrespository.GetItemsAsync
函数。第一个问题可以通过将谓词更改为:

Expression<Func<Subscription, bool>> predicate = x => x.EventType == eventItem.EventType && x.IsActive; 
或为方法提供映射器函数:

 public async Task<List<T>> GetSubscriptions<T, TE>(
        TE eventItem,
        Func<Subscription, T> mapper, 
        params SubscriptionAction[] subscriptionAction)
            where T : Subscription
            where TE : Event
    {
        .....
        return result.Select(mapper).ToList();
    }
 
public异步任务GetSubscriptions(
事件项,
Func mapper,
参数SubscriptionAction[]SubscriptionAction)
其中T:订阅
其中TE:事件
{
.....
返回结果.Select(mapper.ToList();
}

问题出在哪里?是否希望该方法显示在界面中?您必须创建一个新接口,专门用于订阅存储库。@Arcord,目前我遇到编译时错误“无法从'System.Linq.Expression'转换为'System.Linq.Expression.Expression'”,我已尝试过result.OfType().Cast().ToList();但是它回来了0@RakeshKumar这意味着不存在由
GetSubscriptions
返回的
T
类型的实例。这并不奇怪,请举例说明如何使用mapper实现这一点?@RakeshKumar您提供了一个lambda表达式,用于从订阅中构建您的
T
。像
s=>newconcrete{Field1=s.SomeField1,Field2=s.SomeField2,…}
我需要创建一个自定义映射程序,而不是将该方法作为参数传递吗?
 public async Task<List<T>> GetSubscriptions<T, TE>(
        TE eventItem,
        Func<Subscription, T> mapper, 
        params SubscriptionAction[] subscriptionAction)
            where T : Subscription
            where TE : Event
    {
        .....
        return result.Select(mapper).ToList();
    }