2013-05-08 57 views
6

Tôi muốn tạo ra một phương pháp như thế này:Làm thế nào để thực hiện phương pháp với tham số biểu hiện C#

var result = database.Search<EntityType>(x=>x.Name, "Entity Name field value"); 
result = database.Search<EntityType>(x=>x.Id, "Entity Id field value"); 
result = database.Search<EntityType2>(x=>x.Id, "Entity2 Id field value"); 
result = database.Search<EntityTypeAny>(x=>x.FieldAny, "EntityAny FieldAny value"); 

Làm thế nào tôi có thể thực hiện phương pháp này?

+0

bạn muốn tạo phương thức hoạt động tương tự như phương thức 'Tìm kiếm()', theo cách tổng quát? –

+0

@Wim Ombelets yes – Nodir

Trả lời

9

Bạn có thể bật một selector và giá trị vào một vị sử dụng Expression.Equal:

static IQueryable<TSource> Search<TSource, TValue>(
    this IQueryable<TSource> source, 
    Expression<Func<TSource,TValue>> selector, 
    TValue value) 
{ 
    var predicate = Expression.Lambda<Func<TSource,bool>>(
     Expression.Equal(
      selector.Body, 
      Expression.Constant(value, typeof(TValue)) 
     ), selector.Parameters); 
    return source.Where(predicate); 
} 

Sau đó, bạn chỉ cần làm một cái gì đó như:

var result = database.SomeEntities.Search(x => x.SomeProp, "value"); 

Nếu bạn muốn làm điều đó từ cơ sở dữ liệu , thì điều đó tùy thuộc vào cơ sở dữ liệu ; ví dụ, với LINQ-to-SQL bạn có thể thêm một phương pháp bổ sung:

static IQueryable<TSource> Search<TSource, TValue>(
    this System.Data.Linq.DataContext database, 
    Expression<Func<TSource, TValue>> selector, 
    TValue value) where TSource : class 
{ 
    IQueryable<TSource> source = database.GetTable<TSource>(); 
    return Search(source, selector, value); 
} 

và sử dụng:

var result = database.Search<SomeEntity, string>(x => x.SomeProp, "value"); 

thẳng thắn Tôi nghĩ rằng đó là rõ ràng hơn để sử dụng phiên bản database.SomeEntities, mặc dù.

0

làm bạn muốn loại để động

public ReturnType Read<ReturnType>(string FieldName, object dfVal) 
{ 
    if (Res.IsDBNull(Res.GetOrdinal(FieldName))) 
     return dfVal; 
    try { 
     return (ReturnType)Res.GetValue(Res.GetOrdinal(FieldName)); 
    } catch (Exception ex) { 
     return dfVal; 
    } 
} 
+0

Đây là một phần của những gì anh ta muốn, anh ta muốn chỉ định loại thực sự, nhưng cũng muốn sử dụng một vị từ như LinQ có thể. –

+0

nó thực sự không rõ ràng với tôi nếu/làm thế nào điều này trả lời các câu hỏi yêu cầu –

1

tôi chỉ có thể nghĩ về điều này (với 2 đối số generic)

public static IEnumerable<TModel> Search<TModel, TValue>(
     Expression<Func<TModel, TValue>> expression, 
     TValue value 
    ) 
    { 
     return new List<TModel>(); 
    } 

sử dụng

var result = Search<EntityType, int>(x => x.Id, 1); 
var result2 = Search<EntityType, string>(x => x.Name, "The name"); 

bạn có thể thay TValue với đối tượng để tránh đối số chung thứ hai, nhưng tôi sẽ gắn bó với điều này.

Btw. các công trình vĩ đại này kết hợp với helper này ít

public static class ExpressionHelpers 
{ 
    public static string MemberName<T, V>(this Expression<Func<T, V>> expression) 
    { 
     var memberExpression = expression.Body as MemberExpression; 
     if (memberExpression == null) 
      throw new InvalidOperationException("Expression must be a member expression"); 

     return memberExpression.Member.Name; 
    } 
} 

Bây giờ bạn có thể lấy tên của thuộc tính (Id oder Name) trong ví dụ này bằng cách gọi

var name = expression.MemberName(); 
+0

Điều gì nếu tham số thứ hai luôn luôn là một bool, hơn bạn có thể sử dụng nó như: var result2 = Tìm kiếm (x => x.Name == " Tên"); –

+0

tại sao OP cần trích xuất tên thành viên trong trường hợp này? có vẻ như với tôi rằng họ chỉ cần xây dựng biến vị ngữ –

+0

@Marc: đó không phải là một phần của câu hỏi, nhưng tôi cho rằng đó là những gì OP cần biết trong phương thức Tìm kiếm, ví dụ để xây dựng một truy vấn SQL. –

Các vấn đề liên quan