DBContext中使用Entity Framework的泛型

时间:2016-04-22 10:16:14

标签: c# entity-framework generics

我有一个IMstTuver类实现的接口MstTuverIMstTuver包含MaxVersionAgenttype个参数。

public class GetTable<T> where T : IMstTuver
{
    public IMstTuver GetEntities(DbContext context, string agenttype) 
    {
        long maxVersion = context.Set<T>().Max(x => x.MaxVersion);
        IMstTuver mstTuver = context.Set<T>()
                                    .Where(x => x.MaxVersion == maxVersion && 
                                                x.AgentType == agenttype)
                                    .FirstOrDefault();
        return mstTuver;
    }
}

在我班上:

table.GetEntities(MyDbContext, "MSMA") as MstTuver;

我收到错误

  

类型&#39; T&#39;必须是参考类型才能将其用作参数&#39; TEntity&#39;在泛型类型或方法中,System.Data.Entity.DbSet&#39;

请帮忙。

3 个答案:

答案 0 :(得分:3)

Set<T>有一个通用约束,T必须是引用类型,这意味着你的类也需要有一个。修复方法是对调用链上的所有泛型类和/或方法应用以下修改:

public class GetTable<T> where T : class, IMstTuver

答案 1 :(得分:1)

您可以通过在方法中添加angular.module('starter', ['ionic', 'ngCordova']) .run(function($ionicPlatform, GoogleMaps) { $ionicPlatform.ready(function() { // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard // for form inputs) if(window.cordova && window.cordova.plugins.Keyboard) { cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); } if(window.StatusBar) { StatusBar.styleDefault(); } GoogleMaps.init(); }) }) .config(function($stateProvider, $urlRouterProvider) { $stateProvider .state('map', { url: '/', templateUrl: 'templates/map.html', controller: 'MapCtrl' }); $urlRouterProvider.otherwise("/"); }) .factory('Markers', function($http) { var markers = []; return { getMarkers: function(){ return $http.get("http://localhost:8080/markers.php").then(function(response){ markers = response; return markers; }); } } }) .factory('GoogleMaps', function($cordovaGeolocation, Markers){ var apiKey = false; var map = null; function initMap(){ var options = {timeout: 10000, enableHighAccuracy: true}; $cordovaGeolocation.getCurrentPosition(options).then(function(position){ var latLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); var mapOptions = { center: latLng, zoom: 15, mapTypeId: google.maps.MapTypeId.ROADMAP }; map = new google.maps.Map(document.getElementById("map"), mapOptions); //Wait until the map is loaded google.maps.event.addListenerOnce(map, 'idle', function(){ //Load the markers loadMarkers(); }); }, function(error){ console.log("Could not get location"); //Load the markers loadMarkers(); }); } function loadMarkers(){ //Get all of the markers from our Markers factory Markers.getMarkers().then(function(markers){ console.log("Markers: ", markers); var records = markers.data.markers; for (var i = 0; i < records.length; i++) { var record = records[i]; var markerPos = new google.maps.LatLng(record.lat, record.lng); // Add the markerto the map var marker = new google.maps.Marker({ map: map, animation: google.maps.Animation.DROP, position: markerPos }); var infoWindowContent = "<h4>" + record.name + "</h4>"; addInfoWindow(marker, infoWindowContent, record); } }); } function addInfoWindow(marker, message, record) { var infoWindow = new google.maps.InfoWindow({ content: message }); google.maps.event.addListener(marker, 'click', function () { infoWindow.open(map, marker); }); } return { init: function(){ initMap(); } } }) .controller('MapCtrl', function($scope, $state, $cordovaGeolocation) { }); 类型约束来将T声明为引用类型:

class

答案 2 :(得分:0)

我过去做过类似的事情,发现在方法上放置泛型和约束比在类型上更容易。这将允许相同的存储库类型为多个实体类型提供服务(只要它们满足约束条件)。

示例:

public class GetTable
{
    public T GetEntities<T>(DbContext context, string agenttype)where T : class, IMstTuver
    {
        long maxVersion = context.Set<T>().Max(x => x.MaxVersion);
        IMstTuver mstTuver = context.Set<T>().Where(x => x.MaxVersion == maxVersion && x.AgentType == agenttype).FirstOrDefault();
        return mstTuver;
    }
}

将来当您从现有库返回泛型作为泛型时,可以检查要调用的方法的约束并实现相同的约束。在这种情况下,Set<T>方法被限制为类。然后,您可以根据需要添加其他非冲突约束。

DbContext.Set Method

public virtual DbSet<TEntity> Set<TEntity>() where TEntity : class